Skip to content Skip to sidebar Skip to footer

Looping Over Clickable Plot In 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

Solution 1:

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


classLabeler(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 inrange(5):
    data.append(np.random.rand(60+10*i))
l = Labeler(data)

enter image description here

Solution for a console:

The following code runs fine for me.

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


classLabeler(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 plotfor i inrange(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

Post a Comment for "Looping Over Clickable Plot In Python"