Im trying to create a graphing utility to tune my PIDS live so the goal is to be able to send the amount of plots and the amount of data for those plots in the innital object and then call the update function with new data to update the graphs. Currently my example without my class works but of corse to make the graph and data amount vairable i need to integrate it into a class when implemeting that i have goten to the point were i can set data but when calling the fig.canvas.restore_region(bbox)
on my figure im getting an infinite amount of lines allmost like the canvas is not being restored befor the next blit.
class Plot():
def __init__(self,fig,ax,grain,dataAmount,names,colors) -> None:
self.fig = fig
self.ax = ax
self.xData = range(grain)
self.yData = [0] * grain
self.name = names
self.color = colors
self.ln, = self.ax.plot(self.xData, self.yData, animated=True,label=self.name)
self.bg = self.fig.canvas.copy_from_bbox(self.ax.bbox)
self.origBB = self.fig.bbox
self.fig.canvas.blit(self.fig.bbox)
self.ax.legend()
def update(self,ticks,y):
self.fig.canvas.restore_region(self.bg)
self.yData.append(y)
self.yData.pop(0)
self.ln.set_ydata(self.yData)
self.ax.relim()
self.ax.autoscale_view()
self.ax.draw_artist(self.ln)
self.ax.set_title(self.name)
self.ax.legend()
self.fig.canvas.blit(self.ax.bbox)
self.fig.canvas.flush_events()
This is the individual Plot class that acts as an object in the LiveGraph class to create new axes.
class LiveGraph():
def __init__(self,plotNum,names) -> None:
fig = plt.figure()
self.plots = [ Plot(fig,fig.add_subplot(plotNum, 1, i+1),100,1,names[i],i) for i in range(plotNum)]
self.tick = 0
plt.show(block=False)
plt.pause(0.1)
def update(self):
self.tick += 1
for plot in self.plots:
plot.update(self.tick,math.sin(self.tick/10))
if __name__ == "__main__":
LG = LiveGraph(2,["test1","test2"])
while True:
LG.update()
This then the main class to generate and update the window and manage the "axes"/plots
multiple lines This is the output how do i remove the old lines also note that this code is not nearly complete and i still need to implement multiple things i just want the basic graphing to work before that though.
I have tried storing the figure and axes diffrently as i thought passing them was causing issues but my main problem is that my uopdate code is basicaly the same as Minimal example and the example does work but i dont understand why my code doesnt work but the example does considering its allmost the same just in class form.
What you have to do is run plt.pause(.0001)
, so that the restore_region()
method has a cached renderer to call upon when trying to render. Note that it has to be in the context of its construction.