在python中循环可点击的图 [英] Looping over clickable plot in python

查看:26
本文介绍了在python中循环可点击的图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算使用以下类来标记时间序列的特定部分.

I have the following class which I intend to use in labelling specific parts of a time series.

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 笔记本中使用它,以便我可以在这样的循环中使用它:

Now, I want to use this in an ipython notebook so that I can use it in a loop like this:

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

我的问题是,当我循环绘图时,它会等到循环完成后再显示绘图.我要它做的是打开一个图,用红线确定零件,然后进行下一个图.请让我知道如何实现.谢谢!

My problem is that when I loop over the plot, it waits until the loop is finished before displaying the plot. What I want it to do is open a single plot, determine parts using the red line, and then proceed to the next plot. Please let me know how this can be accomplished. Thanks!

推荐答案

jupyter notebook 解决方案

笔记本中的问题是交互式图形阻止了进一步的代码被执行.我能想到的唯一解决方案是让该角色接管对更新的控制.
下面是一个示例(我确定这不是您真正想要的,但是我在理解某些代码的目的时遇到了问题,因此它执行了类似的操作).这个想法是向类提供所有数据,然后类可以循环遍历它.

Solution for jupyter notebook

The problem in a notebook is that the interactive figure prevents further code from being executed. The only solution I can think of is to let the figure take over control over the updates.
The following would be an example (I'm sure it's not what you actually wanted, but I had problems understanding the purpose of some of the code, so it does something similar). The idea would be to provide all the data already to the class, which can then loop through it.

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

以下代码对我来说运行良好.

The following code runs fine for me.

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

这篇关于在python中循环可点击的图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆