How to Update a Plot in Matplotlib

How to update a plot in matplotlib

You essentially have two options:

  1. Do exactly what you're currently doing, but call graph1.clear() and graph2.clear() before replotting the data. This is the slowest, but most simplest and most robust option.

  2. Instead of replotting, you can just update the data of the plot objects. You'll need to make some changes in your code, but this should be much, much faster than replotting things every time. However, the shape of the data that you're plotting can't change, and if the range of your data is changing, you'll need to manually reset the x and y axis limits.

To give an example of the second option:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
line1.set_ydata(np.sin(x + phase))
fig.canvas.draw()
fig.canvas.flush_events()

update plots on matplotlib

Replace this:

self.plot.remove()

with this:

self.plot.clear()

After that it should work.

Is there a way to update the matplotlib plot without closing the window?

One option to update the plot in a loop is to turn on interactive mode and to update the plot using pause.

For example:

import numpy as np
import matplotlib.pyplot as plt
point = plt.plot(0, 0, "g^")[0]
plt.ylim(0, 5)
plt.xlim(0, 5)
plt.ion()
plt.show()

start_time = time.time()
t = 0
while t < 4:
end_time = time.time()
t = end_time - start_time
print(t)
point.set_data(t, t)
plt.pause(1e-10)

However, for more advanced animation I would propose to use the animation class.

Dynamically updating plot in matplotlib

Is there a way in which I can update the plot just by adding more point[s] to it...

There are a number of ways of animating data in matplotlib, depending on the version you have. Have you seen the matplotlib cookbook examples? Also, check out the more modern animation examples in the matplotlib documentation. Finally, the animation API defines a function FuncAnimation which animates a function in time. This function could just be the function you use to acquire your data.

Each method basically sets the data property of the object being drawn, so doesn't require clearing the screen or figure. The data property can simply be extended, so you can keep the previous points and just keep adding to your line (or image or whatever you are drawing).

Given that you say that your data arrival time is uncertain your best bet is probably just to do something like:

import matplotlib.pyplot as plt
import numpy

hl, = plt.plot([], [])

def update_line(hl, new_data):
hl.set_xdata(numpy.append(hl.get_xdata(), new_data))
hl.set_ydata(numpy.append(hl.get_ydata(), new_data))
plt.draw()

Then when you receive data from the serial port just call update_line.

Python: Update plot instead of creating a new one

I think the function ion and clf could do the trick.

import numpy as np
import numpy.random as npr
import matplotlib.pyplot as plt
import seaborn as sns

#Constants
J = 1
h = 1
kbT = 1
beta = 1

#Grid
L = 20 #Dimensions
N = L**2 #Total number of grid points

#Initial configuration
spins = 2*np.random.randint(2, size = (L,L))-1

E = []
i = 0

plt.ion()
plt.figure()
plt.show()

while i < 100000:
for i in range(1,N):
i += 1
s = tuple(npr.randint(0, L, 2)) # Random initial coordinate

# x and y coordinate
(sx, sy) = s
# Periodic boundary condition
sl = (sx-1, sy)
sr = ((sx+1)%L, sy)
sb = (sx, sy-1)
st = (sx, (sy+1)%L)
# Energy
E = spins[s] * ( spins[sl] + spins[sr] + spins[sb] + spins[st] )
if E <= 0 : # If negative, flip
spins[s] *= -1
else:
x = np.exp(-E/kbT) # If positve, check condition
q = npr.rand()
if x > q:
spins[s] *= -1
# Plot (heatmap)
plt.clf()
sns.heatmap(spins, cmap = 'magma')
plt.pause(10e-10)

With the function ion you are making interactive the plot, so you need to:

  • Make it interactive
  • Show the plot
  • Clear the plot in your cycle

Here the reference for the ion function.

Reference for clf is here

Updating Matplotlib plot when clicked

There's nothing wrong with the way you bind your event. However, you only updated the data set and did not tell matplotlib to do a re-plot with new data. To this end, I added the last 4 lines in the onclick method. They are self-explanatory, but there are also comments.

import matplotlib.pyplot as plt
x = [1];
y = [1];

def onclick(event):
if event.button == 1:
x.append(event.xdata)
y.append(event.ydata)
#clear frame
plt.clf()
plt.scatter(x,y); #inform matplotlib of the new data
plt.draw() #redraw

fig,ax=plt.subplots()
ax.scatter(x,y)
fig.canvas.mpl_connect('button_press_event',onclick)
plt.show()
plt.draw()

NOTE: matplotlib in my computer (ubuntu 14.04) changes the scale, so you probably want to look into how to fix the x-y scale.



Related Topics



Leave a reply



Submit