I want to dynamically update the plot of a cell. I.e. the plot is initialized at the beginning of the cell, and updated in a (computationally heavy) for-loop, showing how the computation is progressing. In jupyter notebook, this can be done using pneumatics solution in What is the currently correct way to dynamically update plots in Jupyter/iPython?
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import time
def pltsin(ax, colors=['b']):
x = np.linspace(0,1,100)
if ax.lines:
for line in ax.lines:
line.set_xdata(x)
y = np.random.random(size=(100,1))
line.set_ydata(y)
else:
for color in colors:
y = np.random.random(size=(100,1))
ax.plot(x, y, color)
fig.canvas.draw()
fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
for f in range(5):
pltsin(ax, ['b', 'r'])
time.sleep(1)
I am looking for an equivalent way of doing it in jupyter lab. I tried replacing %matplotlib notebook with %matplotlib widget, using the ipympl library, but that didn't work: The figure only shows once the loop is finished.
What I do not want are solutions like the one proposed by Ziofil in or the one by Paidoo in jupyterlab interactive plot which clear the whole output, as I might print additional things such as e.g. a tqdm progress bar
This is a known for matplotlib for which there happily are workarounds. The relevant issues are: https://github.com/matplotlib/matplotlib/issues/18596 and https://github.com/matplotlib/ipympl/issues/258 and probably the longest explanation is https://github.com/matplotlib/ipympl/issues/290#issuecomment-755377055
Both of these workarounds will work with ipympl.
Use the async ipython event loop following this answer: https://stackoverflow.com/a/63517891/835607
Split the plt.subplots and the updating plot code into two cells. If you wait for a second or two between executing the cells then the plot will have enough time to set itself up properly and it should all work. That looks like this:
Cell 1:
fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
wait until the plot shows up then execute: Cell 2:
for f in range(5):
pltsin(ax, ['b', 'r'])
time.sleep(1)
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