I've noticed that every solution to plotting continuously updating data (I've found) with a continuously increasing length has one huge setback - If the data isn't there immediately, the matplotlib window freezes (says not responding). Take this for example:
from matplotlib import pyplot as plt
from matplotlib import animation
from random import randint
from time import sleep
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
line, = ax.plot([])
x = []
y = []
def animate(i):
x.append(i)
y.append(randint(0,10))
for i in range(100000000):
# Do calculations to attain next data point
pass
line.set_data(x, y)
return line,
anim = animation.FuncAnimation(fig, animate,
frames=200, interval=20, blit=True)
plt.show()
This code works fine without the data acquisition for loop in the animate function, but with it there, the graph window freezes. Take this as well:
plt.ion()
x = []
for i in range(1000):
x.append(randint(0,10))
for i in range(100000000):
# Do calculations to attain next data point
pass
plt.plot(x)
plt.pause(0.001)
Also freezes. (Thank god for that, because using this method it's borderline impossible to close as the graph keeps popping up in front of everything. I do not recommend removing the sleep)
This too:
plt.ion()
x = []
for i in range(1000):
x.append(randint(0,10))
for i in range(100000000):
# Do calculations to attain next data point
pass
plt.plot(x)
plt.draw()
plt.pause(0.001)
plt.clf()
Also this: (copied from https://stackoverflow.com/a/4098938/9546874)
import matplotlib.pyplot as plt
import numpy as np
from time import sleep
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))
for i in range(100000000):
# Do calculations to attain next data point
pass
fig.canvas.draw()
fig.canvas.flush_events()
This is a huge problem, as it's naive to think all the data will come at consistent intervals. I just want a graph that updates when data comes, and doesn't implode in the downtime. Keep in mind the interval between data could change, it could be 2 seconds, or 5 minutes.
EDIT:
After further testing, the FuncAnimation
one can be used, but it's very hacky, and is still a bit broken. If you increase the interval
to above the expected time of animate
, it will work, but every time you pan or zoom the graph, all the data disappears until the next update. So once you have a view, you can't touch it.
Edit:
Changed sleep to a for loop for clarity