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)
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")
Post a Comment for "Looping Over Clickable Plot In Python"