在python中循环遍历可点击的绘图

时间:2017-05-26 06:30:08

标签: python matplotlib

我有以下课程,我打算用它来标记时间序列的特定部分。

class Labeler(object):
    def __init__(self, accel_data, vline=0):
        self.fig = plt.figure(figsize=(10,2))

        self.accel_data = accel_data
        x_ = np.arange(len(self.accel_data))

        self.plot, = plt.plot(x_, self.accel_data, picker=100)
        plt.xlim(0, len(self.accel_data)-1)

        self.final_loc = 0
        self.vline_loc = 0
        self.vline = plt.axvline(self.vline_loc, color='red')

        self.fig.canvas.mpl_connect('button_press_event', self._onclick)

        self.button_next = Button(plt.axes([0.85, 0.78, 0.05, 0.1]), 'Next', color='#32CD32')
        self.button_next.on_clicked(self._nextbutton)

        self.button_done = Button(plt.axes([0.85, 0.65, 0.05, 0.1]), 'Done', color='orange')
        self.button_done.on_clicked(self._donebutton)
        plt.show(block=True)

        self.starts = []

    def _onclick(self, event):
        self.final_loc = self.vline_loc
        self.vline_loc = int(event.xdata)
        self.vline.set_xdata(self.vline_loc)

    def _nextbutton(self, event):
        self.starts.append(['code', self.final_loc])
        n = np.random.randint(1000)
        self.plot.set_xdata(np.arange(n))
        self.plot.set_ydata(np.random.rand(n))
        self.plot.set_title(str(n))

   def _donebutton(self, event):
        plt.close() # close to stop plot

现在,我想在ipython笔记本中使用它,以便我可以在这样的循环中使用它:

for i in range(5):
    l = Labeler(np.random.rand(1000))
    print(l.starts) # print the locs of vertical lines
    cont = input("Press any key to continue")

我的问题是,当我在绘图上循环时,它会等到循环完成后再显示绘图。我想要它做的是打开一个图,使用红线确定零件,然后进入下一个图。请告诉我这是如何实现的。谢谢!

1 个答案:

答案 0 :(得分:0)

jupyter笔记本的解决方案

笔记本中的问题是交互式图形会阻止执行更多代码。我能想到的唯一解决方案就是让这个数字接管对更新的控制权 以下是一个例子(我确定它不是你真正想要的,但我在理解某些代码的目的时遇到了问题,因此它做了类似的事情)。我们的想法是将所有数据提供给类,然后可以循环遍历它。

%matplotlib notebook
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import numpy as np


class Labeler(object):
    def __init__(self, data, vline=0):
        self.fig = plt.figure(figsize=(10,2))
        self.ax = self.fig.gca()
        self.i = 0
        self.data = data 

        self.fig.canvas.mpl_connect('button_press_event', self._onclick)
        self.button_next = Button(plt.axes([0.85, 0.78, 0.05, 0.1]), 'Next', color='#32CD32')
        self.button_next.on_clicked(self._nextbutton)
        self.button_done = Button(plt.axes([0.85, 0.65, 0.05, 0.1]), 'Done', color='orange')
        self.button_done.on_clicked(self._donebutton)

        self.starts = []
        plt.show()


    def _nextbutton(self, event):
        self.i
        self.final_loc = 0
        self.vline_loc = 0
        self.accel_data = self.data[self.i % len(data)]
        self.x = np.arange(len(self.accel_data))
        plt.xlim(0, len(self.accel_data)-1)
        self.plot, = self.ax.plot(self.x, self.accel_data, picker=100)
        self.vline = self.ax.axvline(self.vline_loc, color='red')
        self.starts.append(['code', self.final_loc])
        self.ax.set_title(str(self.i))
        self.i += 1
        self.fig.canvas.draw()


    def _onclick(self, event):
        self.final_loc = self.vline_loc
        self.vline_loc = int(event.xdata)
        self.vline.set_xdata(self.vline_loc)
        self.fig.canvas.draw()


    def _donebutton(self, event):
        #plt.close() # close to stop plot
        self.ax.clear()
        pass

data = []
for i in range(5):
    data.append(np.random.rand(60+10*i))
l = Labeler(data)

enter image description here

控制台解决方案:

以下代码对我来说运行正常。

import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import numpy as np


class Labeler(object):
    def __init__(self, accel_data, vline=0):
        self.fig = plt.figure(figsize=(10,2))
        self.ax = self.fig.gca()
        self.accel_data = accel_data
        x_ = np.arange(len(self.accel_data))

        self.plot, = plt.plot(x_, self.accel_data, picker=100)
        plt.xlim(0, len(self.accel_data)-1)

        self.final_loc = 0
        self.vline_loc = 0
        self.vline = plt.axvline(self.vline_loc, color='red')

        self.fig.canvas.mpl_connect('button_press_event', self._onclick)

        self.button_next = Button(plt.axes([0.85, 0.78, 0.05, 0.1]), 'Next', color='#32CD32')
        self.button_next.on_clicked(self._nextbutton)

        self.button_done = Button(plt.axes([0.85, 0.65, 0.05, 0.1]), 'Done', color='orange')
        self.button_done.on_clicked(self._donebutton)

        self.starts = []
        plt.show(block=True)



    def _onclick(self, event):
        self.final_loc = self.vline_loc
        self.vline_loc = int(event.xdata)
        self.vline.set_xdata(self.vline_loc)

    def _nextbutton(self, event):
        self.starts.append(['code', self.final_loc])
        n = np.random.randint(1000)
        self.plot.set_xdata(np.arange(n))
        self.plot.set_ydata(np.random.rand(n))
        self.ax .set_title(str(n))

    def _donebutton(self, event):
        plt.close() # close to stop plot

for i in range(5):
    l = Labeler(np.random.rand(1000))
    print(l.starts) # print the locs of vertical lines
    cont = raw_input("Press any key to continue")

enter image description here