I'm trying to create a live plot which updates as more data is available.
import os,sys
import matplotlib.pyplot as plt
import time
import random
def live_plot():
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Utilization (%)')
ax.set_ylim([0, 100])
ax.set_xlim(left=0.0)
plt.ion()
plt.show()
start_time = time.time()
traces = [0]
timestamps = [0.0]
# To infinity and beyond
while True:
# Because we want to draw a line, we need to give it at least two points
# so, we pick the last point from the previous lists and append the
# new point to it. This should allow us to create a continuous line.
traces = [traces[-1]] + [random.randint(0, 100)]
timestamps = [timestamps[-1]] + [time.time() - start_time]
ax.set_xlim(right=timestamps[-1])
ax.plot(timestamps, traces, 'b-')
plt.draw()
time.sleep(0.3)
def main(argv):
live_plot()
if __name__ == '__main__':
main(sys.argv)
The above code works. However, I'm unable to interact with the window generated by plt.show()
How can I plot live data while still being able to interact with the plot window?
But did you know that it is also possible to create interactive plots with matplotlib directly, provided you are using an interactive backend? This article will look at two such backends and how they render interactivity within the notebooks, using only matplotlib.
The live plotting function is capable of producing high-speed, high-quality, real-time data visualization in Python using matplotlib and just a few lines of code.
To create a real-time plot, we need to use the animation module in matplotlib. We set up the figure and axes in the usual way, but we draw directly to the axes, ax , when we want to create a new frame in the animation.
You can choose to run matplotlib either interactively or non- interactively. For the interactive mode, the plot gets updated as you go along. For non-interactive, the plot doesn't show up until you've finished everything. To switch between the two: plt.
Use plt.pause()
instead of time.sleep()
.
The latter simply holds execution of the main thread and the GUI event loop does not run. Instead, plt.pause
runs the event loop and allows you to interact with the figure.
From the documentation:
Pause for interval seconds.
If there is an active figure it will be updated and displayed, and the GUI event loop will run during the pause.
If there is no active figure, or if a non-interactive backend is in use, this executes time.sleep(interval).
Note
The event loop that allows you to interact with the figure only runs during the pause period. You will not be able to interact with the figure during computations. If the computations take a long time (say 0.5s or more) the interaction will feel "laggy". In that case it may make sense to let the computations run in a dedicated worker thread or process.
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