43

I am using Jupyter Notebook for plotting piechart figures.

In first cell with my code I have a magic command %matplotlib inline and after this magic command I run my code, everything works fine and my figure renders.

But in second cell when I set %matplotlib notebook for interactive plotting my figure won't render after running this second cell.

I need to restart kernel and run cell with %matplotlib notebook again and cannot run %matplotlib inline command before that.

Here is my code for first cell with %matplotlib inline, which renders fine:

import matplotlib.pyplot as plt

%matplotlib inline

labels = "No", "Yes"
sizes = [100, 50]

fig, ax = plt.subplots(figsize=(6, 6))

_, texts, autotexts = ax.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%',
             shadow=False, startangle=90)

ax.axis('equal')

After that I have second cell with same code, just %matplotlib inline is changed to %matplotlib notebook. Figure won't render after I run this cell and I need to restart kernel and run this cell again.

Why?

1
  • Load and using library change/store more class and variables, use copy+rename module class as external module. Single import single usage...
    – dsgdfg
    Commented Apr 21, 2017 at 14:59

4 Answers 4

54

You just have the wrong order of your commands. A backend should be set before importing pyplot in jupyter. Or in other words, after changing the backend, pyplot needs to be imported again.

Therefore call %matplotlib ... prior to importing pyplot.

In first cell:

%matplotlib inline
import matplotlib.pyplot as plt
plt.plot([1,1.6,3])

In second cell:

%matplotlib notebook
#calling it a second time may prevent some graphics errors
%matplotlib notebook  
import matplotlib.pyplot as plt
plt.plot([1,1.6,3])

13
  • 7
    "A backend must be set before importing pyplot." I don't believe that's true. For years, I've always used "%matplotlib inline" after importing pyplot, with no problem. I just tried your code, moving the magics to after the pyplot imports, and it ran correctly (I did need the 2nd "%matplotlib notebook" command; thanks for that tip). Note also that you can't put a comment after "%matplotlib notebook". You may be confusing requirements of the "use()" command; see #3 here: matplotlib.org/2.2.3/tutorials/introductory/usage.html#id3
    – Tom Loredo
    Commented Oct 5, 2018 at 4:59
  • Thanks for commenting. Changing the backend via the magic commands does not work reliably, but you can circumvent that by setting the backend before the pyplot import. If you never experienced any problems with the inverse, that's probably lucky. I modified the sentence above to be more accurate though. Commented Oct 5, 2018 at 11:33
  • 2
    Part of why I was skeptical was the suggestion to re-import pyplot after setting/changing the backend. Importing an already-imported module in Python normally does nothing (if the module is already imported, import normally only does name binding to the already-imported module; see effbot.org/zone/import-confusion.htm). Does pyplot have some special import behavior?
    – Tom Loredo
    Commented Oct 7, 2018 at 16:08
  • 3
    Why does this answer has so many upvotes when it is based on completely wrong assumption? As Tom Loredo noted, the second import matplotlib.pyplot as plt does nothing. This is just some python101 stuff(stackoverflow.com/questions/437589/…)
    – user5538922
    Commented Apr 21, 2020 at 3:13
  • 2
    @ImportanceOfBeingErnest It seems the backend doesn't need to be set before importing pyplot. At least in my jupyter notebook.
    – user5538922
    Commented May 12, 2020 at 1:11
6

Edit: turns out that you can in fact change backends dynamically on jupyter. Still leaving the answer here because I think it's relevant and explains some matplotlib magic that can pop out sometimes.

The magic command, as seen in the source code, is calling matplotlib.pyplot.switch_backend(newbackend) to change the backend. As stated in matplotlib's docs:

matplotlib.pyplot.switch_backend(newbackend)

Switch the default backend. This feature is experimental, and is only expected to work switching to an image backend. e.g., if you have a bunch of PostScript scripts that you want to run from an interactive ipython session, you may want to switch to the PS backend before running them to avoid having a bunch of GUI windows popup. If you try to interactively switch from one GUI backend to another, you will explode..

So you really have to restart the kernel each time you switch backends, because matplotlib has a problem to switch the backend after being used.

This problem is mainly due to incompatibilities between different main-loops of the GUI backend. Because normally each backend is also taking care of threads and user input you can't run Qt and Tkinter side-by-side. So that limitation is carried over to jupyter.

Also see this question: How to switch backends in matplotlib / Python

1
  • I don't think that is true (anymore). See my answer, where backends can easily switched by calling the magic commands as usual. Commented Apr 21, 2017 at 19:49
1

Update for 2024 JupyterLab and Jupyter Notebook

The currently accepted answer did not work for me in JupyterLab v4.2. It seems things have changed since it was written some years ago.

I give what I found to be presently working, to give interactive Matplotlib plots:

  • The %matplotlib <backend> magic command is enough;
  • The name of the interactive backend is widget or ipympl (the former is an alias of the latter). The ipyml package must be installed.
  • One has to close the figure when switching back to the inline backend.

Here is a minimal example:

First cell

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 7, 100)
plt.plot(np.sin(x))

enter image description here

Second cell

%matplotlib widget

plt.plot(np.sin(2*x))
plt.show()

enter image description here

Third cell

%matplotlib inline

plt.close()
plt.plot(np.sin(3*x))

enter image description here

Important

No new plot is produced if I comment the plt.close() command in the third cell. Instead, the second cell is updated with the output of the third cell as follows.

enter image description here

3
  • 1
    I have some suggestions because you still aren't bringing this up to being current. The heading would be best as 'Update for 2024 JupyterLab & Jupyter Notebook 7+' or simply, 'Update for 2024 Jupyter'. Jupyter Notebook 7+ is built on JupyterLab components and so the same things usually hold and work now in both. Importantly, "name of the interactive backend is widget" is not the case. The real name is ipympl. Please suggest installing ipympl and using %matplotlib ipympl. While it works, widget is only for legacy users who were using things in the interim. The real explicit thing to ...
    – Wayne
    Commented Sep 22, 2024 at 18:10
  • 1
    <continued> use these days is %matplotlib ipympl because it makes it very apparent what is involved. See here where it says," Matplotlib Jupyter Integration" and "ipympl enables the interactive features of matplotlib in the Jupyter notebook and in JupyterLab." Also pay very close attention to the 'Basic Example' on the ipympl documentation page where it makes it clear it supports %matplotlib widget while that not being the explicit recommendation.
    – Wayne
    Commented Sep 22, 2024 at 18:14
  • See also here.
    – Wayne
    Commented Sep 22, 2024 at 18:19
-1

In Jupyter notebook, you have to enter matplotlib notebook in the same line as the one you want to run. Even if you enter "inline" then followed by "notebook", it still won't work. It has to be on the same line as the code you want to render.

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.