I will be collecting data in real time from an Arduino and am trying to find a way to show updates in this data on a pyplot bar chart as it comes in. The sample code below is a simplified version of what I'd like to achieve, but the FuncAnimation method is too slow or, at least, I'm not utilizing it correctly. I'd really like to update all 500 points at once instead of one at a time each ms since a new set of data will come in as fast as once every 10 ms in the actual application.
If anyone can point out how to utilize animation better (or propose a different method entirely), I'd greatly appreciate it. Thanks in advance.
import numpy as np
from matplotlib import animation as animation, pyplot as plt, cm
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
fig = plt.figure()
x = np.linspace(1,500,num=500)
counts = np.random.randint(0, 100, size=500)
bars = plt.bar(x, counts, facecolor='green', width=1)
def animate(frame):
global bars
counts = np.random.randint(0, 100, size=500)
for i in range(len(counts)):
bars[frame].set_height(counts[i])
ani = animation.FuncAnimation(fig, animate, frames=len(x), interval = 1)
plt.xlabel("Time (ms)")
plt.ylabel("Counts")
plt.title("Window Counts")
plt.ylim([0,100])
plt.xlim([0,500])
plt.show()
CodePudding user response:
With the help of chrslg I was able to get this to work exactly how I wanted. The fact that the bars[].set_height call was using 'frame' from FuncAnimation as an index slipped past me. What I really wanted was to use the index from my for loop as the index of bars[].set_height and set frames in FuncAnimation to 1. This way, the whole chart will be updated with new random values each ms, which is what I wanted.
import numpy as np
from matplotlib import animation as animation, pyplot as plt, cm
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
fig = plt.figure()
x = np.linspace(1,500,num=500)
counts = np.random.randint(0, 100, size=500)
bars = plt.bar(x, counts, facecolor='green', width=1)
def animate(frame):
global bars
counts = np.random.randint(0, 100, size=500)
for index, value in enumerate(counts):
bars[index].set_height(value)
ani = animation.FuncAnimation(fig, animate, frames=1, interval = 1)
plt.xlabel("Time (ms)")
plt.ylabel("Counts")
plt.title("Window Counts")
plt.ylim([0,100])
plt.xlim([0,500])
plt.show()