Reputation: 89
Given a matrix (list of lists)
A = [[1, 2, 3],
[4, 6, 8],
[9, 12, 15]]
and a list x = [1, 2, 3]
.
Each row j (0 <= j <= 2)
of A
consists of y-values so that 3 straight lines in total can be created in combination with x
.
Now I want to plot these straight lines in the same plot with a special feature. If the user clicks on the graphic, an event handler should receive the x-position and create another plot right below the first one. This plot should be 1D and only visualise the data of the column in A
whose index is given by the x-position.
Example: A click on x = 1 should plot [1 4 9]
, x = 2 should plot [2 6 12]
and so on.
I have already tried to add a subplot using figure1.add_subplot(211)
for the first plots and figure1.add_subplot(212)
within the event handler and it also did not work.
A = [[1 2 3], [4 5 6], [7 8 9]]
x = [1 2 3]
figure1 = plt.figure()
plt.plot(x, A[0])
plt.plot(x, A[1])
plt.plot(x, A[2])
def onclick(event):
Y = [A[i][int(event.xdata)] for i in range(0, 3)]
plt.plot(Y)
figure1.canvas.mpl_connect('button_press_event', onclick)
Upvotes: 0
Views: 254
Reputation: 25100
I have the following script that does what was asked for in the question:
ax.relim(); ax.autoscale_view()
(aknowledgement, this comes from this answer from asmus) in the callback or fix suitable limits beforehand, as I have opted to do.here it is the script:
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
def get_x(event):
x = event.xdata
# if you clic outside the graph, do nothing
if x is None : return
# from abscissa to column index
i = int(round(x)-1)
# update the line ordinates --- this is much faster than redrawing
# the line, in this example it doesn't matter but possibly one
# deals with larger data sets...
line.set_ydata([row[i] for row in A])
# we start with a clean subplot, if we haven't already placed a
# line in it it's high time to do that
if a2.lines == [] : a2.add_line(line)
# eventually it's the moment of redrawing the whole figure
fig.canvas.draw_idle()
# the data
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
x = [ 1, 2, 3]
# THE key issue is to set properly and in advance all the axes,
# hence the share{x,y}
f, (a1, a2) = plt.subplots(2, 1, sharex='col', sharey='col')
a1.grid(1), a2.grid(1)
# the first subplot, nitpick: adjust the y limits
a1.plot(x, list(zip(*A)))
a1.set_ylim(0, 10)
# prepare a line to be plotted in the second subplot
line = Line2D([1,2,3], [0,0,0], color='black')
# bind our callback and show the figure
f.canvas.mpl_connect('button_press_event', get_x)
plt.show()
Upvotes: 1