Issue
I've developed an gui with python pyqt. There I have a matplotlib figure with x,y-Data and vlines that needs to change dynamically with a QSlider.
Right now I change the data just with deleting everything and plot again but this is not effective
This is how I do it:
def update_verticalLines(self, Data, xData, valueSlider1, valueSlider2, PlotNr, width_wg):
if PlotNr == 2:
self.axes.cla()
self.axes.plot(xData, Data, color='b', linewidth=2)
self.axes.vlines(valueSlider1,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
self.axes.vlines(valueSlider2,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
self.axes.text(1,0.8*max(Data),str(np.round(width_wg,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.text(1,0.6*max(Data),"Pos1: "+str(round(valueSlider1,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.text(1,0.4*max(Data),"Pos2: "+str(round(valueSlider2,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.grid(True)
self.draw()
"vlines" are LineCollections in matplotlib. I searched in the documentation but could not find any hint to a function like 'set_xdata' How can I change the x value of vertical lines when they are already drawn and embedded into FigureCanvas?
I have the same problem with changing the x and y data. When trying the known functions of matplotlib like 'set_data', I get an error that AxisSubPlot does not have this attribute.
In the following is my code for the FigureCanvas Class. The def update_verticalLines should only contain commands for changing the x coord of the vlines and not complete redraw.
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
FigureCanvas.__init__(self, fig)
self.setParent(parent)
class DynamicMplCanvas(MplCanvas):
def __init__(self, *args, **kwargs):
MplCanvas.__init__(self, *args, **kwargs)
def update_figure(self, Data, xData, Path, PlotNr):
if PlotNr==0:
self.axes.cla()
self.style1(self.axes)
self.axes.grid(True)
self.axes.plot(xData, Data, color='r', linewidth=2)
self.axes.set_xlim(0,max(xData))
self.axes.set_ylim(1.1*min(Data),1.1*max(Data))
self.draw()
if PlotNr==1:
self.axes.cla()
self.style2(self.axes)
self.axes.grid(True)
self.axes.plot(xData, Data, color='b', linewidth=2)
self.axes.set_xlim(0,max(xData))
self.axes.set_ylim(1.1*min(Data),1.1*max(Data))
self.vLine1 = self.axes.axvline(color='r')#vlines(len(Data)/4,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
self.vLine2 = self.axes.vlines(len(Data)/2,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
#self.vLine1.set_xdata(0)
self.draw()
def update_verticalLines(self, Data, xData, valueSlider1, valueSlider2, PlotNr, width_wg):
if PlotNr == 2:
self.axes.cla()
self.axes.plot(xData, Data, color='b', linewidth=2)
self.axes.set_ydata(xData)
self.axes.vlines(valueSlider1,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
self.axes.vlines(valueSlider2,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
self.axes.text(1,0.8*max(Data),str(np.round(width_wg,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.text(1,0.6*max(Data),"Pos1: "+str(round(valueSlider1,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.text(1,0.4*max(Data),"Pos2: "+str(round(valueSlider2,2))+u"µm", fontsize=16, bbox=dict(facecolor='m', alpha=0.5))
self.axes.grid(True)
self.draw()
#test=self.axes
#self.vLine1 = plt.vlines(0,min(Data),max(Data),color='r',linewidth=1.5, zorder = 4)
#help(test)
#print test.get_axes()
#print test.properties()
#test.set_axes()
#return test
self.style2(self.axes)
self.axes.relim()
self.axes.autoscale_view(True,True,True)
self.draw()
if PlotNr == 1:
self.axes.cla()
self.axes.plot(xData, Data, color='r', linewidth=2)
self.axes.vlines(valueSlider1,min(Data),max(Data),color='b',linewidth=1.5, zorder = 4)
self.axes.vlines(valueSlider2,min(Data),max(Data),color='b',linewidth=1.5, zorder = 4)
self.axes.grid(True)
self.style1(self.axes)
self.axes.relim()
self.axes.autoscale_view(True,True,True)
self.draw()
Thanks
Solution
When you create the vlines, save a reference to them, e.g.
self.my_vlines = self.axes.vlines(...)
so that when you want to change them, you can just remove and replace them, e.g.
self.my_vlines.remove()
self.my_vlines = self.axes.vlines(...)
# Redraw vline
self.axes.draw_artist(self.my_vlines)
# Add newly-rendered lines to drawing backend
self.update()
# Flush GUI events for figure
self.flush_events()
By the way, in the future you should try your best to pare down your code sample to just the essential parts. Having a lot of unnecessary sample code makes it hard to understand your question. :)
Answered By - Craigular Joe
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.