Search code examples
matplotlibjupyter-notebookjupyter-lab

interactive plot in notebook vs jupyterlab


With Jupyter Notebook 6.5.4, Python 3.8.13, IPython 8.12.0, I can make an interactive plot with:

from ipywidgets import interactive, FloatSlider
import matplotlib.pyplot as plt
import numpy as np
%matplotlib notebook 
#inline doesn't work in jupyter notebook 
m_widget = FloatSlider(min=-2, max=2, step=.5, readout_format='.3f', continuous_update=False)
b_widget = FloatSlider(min=-5, max=5, step=.5, readout_format='.1e', continuous_update=False)
fig, ax = plt.subplots(figsize=(6,4))
x = np.linspace(-10, 10, num=1000)
l, = ax.plot(x, r_widget.value * x + c_widget.value)
ax.set_ylim(-5, 5)
def f(m, b):
    l.set_ydata(m*x+b) 
    fig.canvas.draw()
interactive_plot = interactive(f, m = m_widget, b=b_widget )
interactive_plot 

and the interactive plot works with pan/zoom and updates as I slide the widgets. I thought this technique would be better/faster/more efficient since I am not creating the figure with each slider adjustment, but instead only updating the line data. Also, I found if I didn't update the line data directly, I would end up with new lines on each update, instead of just changing the line. I switched to jupyterlab 3.6.3, and a few others have asked about the differences with interactive plotting between jupyterlab and jupyter notebook, however those solutions are 3-4 years old and are not solving my issue. In jupyterlab, I can only get interactive to work with %matplotlib inline and in the following style:

%matplotlib inline  
from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np
m_widget = FloatSlider(min=-2, max=2, step=.5, readout_format='.3f', continuous_update=False)
b_widget = FloatSlider(min=-5, max=5, step=.5, readout_format='.1e', continuous_update=False)
def f(m, b):
    fig, ax = plt.subplots(figsize=(6,4))
    x = np.linspace(-10, 10, num=1000)
    ax.plot(x, m * x + b)
    ax.set_ylim(-5, 5)
    plt.show()

interactive_plot = interactive(f, m=m_widget, b=b_widget)
interactive_plot 

Using %matplotib notebook and %matplotlib widget both result in Javascript Error: IPython is not defined. If I move the fig, ax = plt.subplots(figsize=(6,4)) above the function f, the plot does nothing. This answer has not changed the behavior I'm describing. I have ipympl 0.9.3. Should I not expect my older style of making interactive plots to work? Is there even an advantage to that (besides being able to pan/zoom)?


Solution

  • I found this discussion and so I did conda install nodejs and now the first code block in my question works with %matplotlib widget and also %matplotlib ipympl, with both types of interaction (the widgets and the pan/zoom).