Dynamically Updating Plot in Matplotlib

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.

How do I plot in real-time in a while loop using matplotlib?

Here's the working version of the code in question (requires at least version Matplotlib 1.1.0 from 2011-11-14):

import numpy as np
import matplotlib.pyplot as plt

plt.axis([0, 10, 0, 1])

for i in range(10):
y = np.random.random()
plt.scatter(i, y)
plt.pause(0.05)

plt.show()

Note the call to plt.pause(0.05), which both draws the new data and runs the GUI's event loop (allowing for mouse interaction).

Updating a matplotlib graph dynamically

I created the code with the understanding that the intent of the question was to draw a graph based on the row-by-row data by retrieving the values from an updated, localized text file. The main points that I modified are the initial settings and updating the values in the animation function.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
from matplotlib.animation import PillowWriter
#from IPython.display import HTML

pullData = open("sampleText.txt","r").read()
dataArray = pullData.split('\n')
frm = len(dataArray)

fig = plt.figure()
ax1 = plt.axes(xlim=(0, size), ylim=(0, size))

line, = ax1.plot([],[], 'r-', lw=3)
xar = []
yar = []

def animate(i):
if i < size:
x,y = dataArray[i].split(',')
xar.append(int(x))
yar.append(int(y))
line.set_data(xar, yar)
ax1.set_ylim(0, max(yar)+3)
return line

ani = animation.FuncAnimation(fig, animate, frames=frm, interval=200, repeat=False)
ani.save('plot_ani_test.gif', writer='pillow')
# jupyter lab
# plt.close()
# HTML(ani.to_html5_video())

Sample Image

update matplotlib figure dynamically

You upate the ydata of smoothed_histogram, you can do the same thing with your * markers:

import numpy as np
import matplotlib.pyplot as plt

n = 100
x = np.arange(n)
y = np.sort(np.random.random(n))

fig, ax = plt.subplots()
ax.plot(x, y)
h_marker = ax.plot(x[0], y[0], marker='o', color='r')[0]

for i in range(n):
h_marker.set_data(x[i], y[i])
plt.pause(0.01)

plotting dynamic data using matplotlib

There are better ways to do this using the matplotlib animation API,
but here's a quick and dirty approach:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 10, 0.1)
y = np.sin(x)

plt.ion()
ax = plt.gca()
ax.set_autoscale_on(True)
line, = ax.plot(x, y)

for i in xrange(100):
line.set_ydata(y)
ax.relim()
ax.autoscale_view(True,True,True)
plt.draw()
y=y*1.1
plt.pause(0.1)

The key steps are:

  1. Turn on interactive mode with plt.ion().
  2. Keep track of the line(s) you want to update, and overwrite their data instead of calling plot again.
  3. Give Python some time to update the plot window by calling plt.pause.

I included the code to autoscale the viewport, but that's not strictly necessary.



Related Topics



Leave a reply



Submit