matplotlib widget disappears after first use

Question:

I’m trying once more to use interactive matplotlib plots in Jupyter Notebooks for my students. My plan is to use JupyterLab as the plain Notebook interface is not very well liked among students. Here is a two-cell MWE notebook:

import numpy as np
%matplotlib widget
import matplotlib.pyplot as plt

Next cell:

plt.figure(1)
x = np.arange(100)
y = x*x
plt.plot(x,y)
plt.show()

When I run these cells I do get an interactive Matplotlib plot. But when I run the second cell a second time, the plot window vanishes without a warning or error and only comes back when I rerun the first cell before the second cell. The classic notebook interface shows the same behaviour, dropping plt.show() or plt.figure() also makes no difference.

I’m running the Jupyter Server locally on a Windows 10 machine in a venv environment, the following versions are installed:

Python           : 3.8.2
ipympl           : 0.7.0

jupyter core     : 4.7.1
jupyter-notebook : 6.3.0
qtconsole        : not installed
ipython          : 7.23.1
ipykernel        : 5.5.4
jupyter client   : 6.1.12
jupyter lab      : 3.0.14
nbconvert        : 6.0.7
ipywidgets       : 7.6.3
nbformat         : 5.1.3
traitlets        : 5.0.5

To my non-expert eyes the messages during startup seem to be ok:

[I 2021-05-12 10:10:48.065 LabApp] JupyterLab extension loaded from d:envspyfda_38libsite-packagesjupyterlab
[I 2021-05-12 10:10:48.065 LabApp] JupyterLab application directory is D:envspyfda_38sharejupyterlab
[I 2021-05-12 10:10:48.069 ServerApp] jupyterlab | extension was successfully loaded.
[I 2021-05-12 10:10:48.488 ServerApp] nbclassic | extension was successfully loaded.
[I 2021-05-12 10:10:48.489 ServerApp] Serving notebooks from local directory: D:Datenxxx
[I 2021-05-12 10:10:48.489 ServerApp] Jupyter Server 1.6.4 is running at:
[I 2021-05-12 10:10:48.489 ServerApp] http://localhost:8888/lab?token=xxxx

The only (maybe) relevant warning I get is

[W 2021-05-12 10:10:55.256 LabApp] Could not determine jupyterlab build status without nodejs 

Am I doing something wrong or are interactive plots with ipympl not yet mature enough for a BYOD course?

Asked By: Chipmuenk

||

Answers:

It works when activate the matplotlib interactive support every time by moving the magic command into the second cell:

%matplotlib widget
plt.figure(1)
x = np.arange(100)
y = x*x
plt.plot(x,y)
plt.show()
Answered By: jf_

While the accepted answer technically works, it is not very Pythonic. More standard ways to get the behavior you want:

  1. Put plt.figure() in every cell that you want a new figure. The reason you are having issues in your code is you keep calling plt.figure(1).

  2. Better yet, use the object-oriented api. This is generally more powerful anyway. So in each cell, something like:

    fig, ax = plt.subplot()    
    ax.plot(x,y)
    

Explanation

The problem the OP is seeing is a known issue and the expected behavior. For reasons I don’t quite understand, ipympl is not meant to be a drop-in replacement for the other matplotlib front-end clients (qt and inline). This is discussed at two issues at the repo:

The developers are aware of the disparities in behavior, and it is discussed at those issues.

It would help if the documentation were clear about the expected behavior, in particular the expected deviations from the standard APIs.

Answered By: eric