单击事件后如何在第一个图形正下方的图形中创建新图?

How to create a new plot in a figure right below the first one after click event?

给定一个矩阵(列表列表)

A = [[1, 2, 3],
     [4, 6, 8],
     [9, 12, 15]]

和一个列表 x = [1, 2, 3]

A 的每一行 j (0 <= j <= 2)y 值组成,因此总共可以创建 3 条直线与 x.

现在我想用一个特殊的特征在同一个图中绘制这些直线。如果用户单击图形,事件处理程序应接收 x 位置并在第一个图的正下方创建另一个图。该图应该是一维的,并且只可视化 A 中列的数据,其索引由 x 位置给出。

示例:点击 x = 1 应该绘制 [1 4 9]x = 2 应该绘制 [2 6 12] 等等。

我已经尝试在事件处理程序中使用 figure1.add_subplot(211) 添加子图,并在事件处理程序中使用 figure1.add_subplot(212) 添加子图。

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)

我有以下脚本可以执行问题中的要求:

  1. 回调函数被大量评论
  2. 一个关键点是轴限制不会自动更新,你可以在回调中使用ax.relim(); ax.autoscale_view()(知识,这来自这个 from asmus)或者预先修复合适的限制,因为我已经选择了。

这是脚本:

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()