重绘并清除一部分独立的情节

时间:2016-03-21 13:16:08

标签: python matplotlib

由于性能问题,我想稍微更改一个情节,而不重绘完整的情节。

enter image description here

当鼠标在上图上移动时,我想在光标x位置的所有图表上绘制虚线垂直线。由于性能,我不想再绘制整个图,而只是绘制垂直线。

我能够通过点击axvline()来显示线条,但是如果再次点击该图块,我就有了删除绘制线条的问题。

我想在每个情节上都有第二层,我可以画出并清楚独立。后来我想在绘图和垂直线的交点上画一个点并打印下面的y值。

我发现this关于绘制独立的绘图部分,如标签和比例。但我想重新绘制图表的一部分。反正是否有额外的层或其他方式有效地绘制?

该应用程序基于PyQt4 matplotlib.backends.backend_qt4agg

IPython笔记本的最小布局代码

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

gs = gridspec.GridSpec(3, 2, wspace=0.1, height_ratios=[3,1,1])
main_plot = plt.subplot(gs[0, :])
sub_plots = [plt.subplot(gs[1, x]) for x in range(2)]
sub_plots.extend([plt.subplot(gs[2, x]) for x in range(2)])

main_plot.plot(np.arange(100), [np.random.randint(0, 100) for y in range(100)])
for sub_plot in sub_plots:
    sub_plot.plot(np.arange(100), [np.random.randint(0, 100) for y in range(100)])          

我的应用程序中减少了代码

def __init__(self):
    self.figure = Figure((20.0, 10.0), dpi=100)
    self.figure.patch.set_color('w')

    gs = gridspec.GridSpec(3, 2, wspace = 0.1, height_ratios=[3, 1, 1])
    self.main_plot = self.figure.add_subplot(gs[0, :])
    self.sub_plots = [self.figure.add_subplot(gs[1, x]) for x in range(2)]
    self.sub_plots.extend([self.figure.add_subplot(gs[2, x]) for x in range(2)])

    self.plotCanvas = FigureCanvas(self.figure)
    self.plotCanvas.mpl_connect('button_press_event', self._on_click)

def _on_click(self, event):
    if event.inaxes == self.main_plot:
        self.main_plot.axvline(event.xdata)
        for plot_area in self.sub_plots:
            plot_area.axvline(event.xdata)

        self.plotCanvas.draw()
        return

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用set_xdata?尝试在__init__中添加对axvline对象的引用,即self.vline = ax.axvline(some_x)(如果要在使用之前隐藏vline,可以将其放在xlims之外)。现在在_on_click内,您拨打self.vline.set_xdata(event.xdata)而不是制作新的axvline。由于艺术家已经出现在情节中,因此mpl只应重绘self.vline

请尝试以下示例,了解其工作原理:

import matplotlib as plt
fig, ax = plt.subplots(1, 1)
fig.show() #note that show will only "work" if you use ipython. use plt.show() otherwise.
vl = ax.axvline(0.3)
fig.canvas.draw()
vl.set_xdata(0.6)
fig.canvas.draw()
# plt.show()

在绘制圆圈进行拦截时,您可以使用相同的技巧,即在__init__中引用它,然后使用self.circle.set_data(new_x, new_y)