I have a question concerning updating dynamically scatter plots from matplotlib. I have the following class in Python
''' PolygonHandler.py - Python source for polygon handling '''
import numpy as np
import matplotlib.pyplot as plt
class PolygonHandler:
# Constructor
def __init__(self):
self.X = []
self.Y = []
self.numberPoints = 0
# Print the polygon
def draw(self):
plt.scatter(self.X,self.Y)
plt.draw()
def update(self):
for i in range(1,self.numberPoints):
self.X[i] += np.random.normal()*0.01
self.Y[i] += np.random.normal()*0.01
# append a point
def add(self,x,y):
self.numberPoints += 1
self.X.append(x)
self.Y.append(y)
This class is used in a real time loop that receives information and adds the points to the PolygonHandler class. Now for the purpose of an example, I want to design the following loop
P = PolygonHandler()
P.add(1,1)
P.add(2,2)
P.add(1,2)
plt.ion()
plt.show()
while (True):
P.draw()
P.update()
How can I tell the interpreter to draw the scatter plots, and once done to remove the former points after updating ? Right now, my plot draws the points and all their previous positions.
Vincent
Thanks a lot for your help
PS : An other problem I have is that the window that is opened by matplotlib freezes and stops answering as soon as I clicked on it (for example to move it to another place on my screen), is there a way to prevent that ?
Here you have one way to go, using animations from matplotlib.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
class PolygonHandler:
# Constructor
def __init__(self):
self.X = []
self.Y = []
self.numberPoints = 0
self.fig , ax = plt.subplots()
self.sc = ax.scatter(self.X,self.Y)
ax.set_xlim(0,3)
ax.set_ylim(0,3)
# Print the polygon
def update(self,_):
for i in range(self.numberPoints):
self.X[i] += np.random.normal()*0.01
self.Y[i] += np.random.normal()*0.01
self.sc.set_offsets(np.column_stack((self.X,self.Y)))
return self.sc,
# append a point
def add(self,x,y):
self.numberPoints += 1
self.X.append(x)
self.Y.append(y)
And this way you plot your 3 random walks:
P = PolygonHandler()
P.add(1,1)
P.add(2,2)
P.add(1,2)
ani = animation.FuncAnimation(P.fig, P.update, interval=10,blit=False)
the key element is the method set_offsets(), that substitutes the data of the scatter plot. Then such scatter object is returned by update(), so that matplotlib knows that it must be updated. For another source with a matplotlib animation handled by a class, see this matplotlib example.
With blit=True in the last line the animation is faster, but depending on your OS it may not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With