908

What exactly is the use of %matplotlib inline?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Rishabh
  • 9,367
  • 4
  • 11
  • 6
  • 51
    It is a magic function that renders the figure in a notebook (instead of displaying a dump of the figure object). A simple Matplotlib tutorial is found here https://www.data-blogger.com/2017/11/15/python-matplotlib-pyplot-a-perfect-combination/. – www.data-blogger.com Nov 15 '17 at 13:42
  • 15
    [You can check the available backends](https://ipython.readthedocs.io/en/stable/interactive/magics.html) (like `inline`) by entering: `%matplotlib --list`. – Luis Jan 11 '19 at 16:22
  • 2
    Possible duplicate of [How to make IPython notebook matplotlib plot inline](https://stackoverflow.com/questions/19410042/how-to-make-ipython-notebook-matplotlib-plot-inline) – desertnaut Mar 16 '19 at 11:53
  • I recently saw a good twitter thread about this: https://twitter.com/tedpetrou/status/1238812794218307590?lang=en – Scott Boston Jul 06 '21 at 13:37
  • Related: [matplotlib python inline on/off](https://stackoverflow.com/questions/30878666/matplotlib-python-inline-on-off) and how to change backend – user2314737 Apr 14 '22 at 07:05

12 Answers12

509

%matplotlib is a magic function in IPython. I'll quote the relevant documentation here for you to read for convenience:

IPython has a set of predefined ‘magic functions’ that you can call with a command line style syntax. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. Lines magics can return results and can be used in the right hand side of an assignment. Cell magics are prefixed with a double %%, and they are functions that get as an argument not only the rest of the line, but also the lines below it in a separate argument.

%matplotlib inline sets the backend of matplotlib to the 'inline' backend:

With this backend, the output of plotting commands is displayed inline within frontends like the Jupyter notebook, directly below the code cell that produced it. The resulting plots will then also be stored in the notebook document.

When using the 'inline' backend, your matplotlib graphs will be included in your notebook, next to the code. It may be worth also reading How to make IPython notebook matplotlib plot inline for reference on how to use it in your code.

If you want interactivity as well, you can use the nbagg backend with %matplotlib notebook (in IPython 3.x), as described here.

Community
  • 1
  • 1
Aurora0001
  • 13,139
  • 5
  • 50
  • 53
  • 11
    ok, but what is the alternative: how can I see the plots if there is no such magic activated? – JaakL Oct 22 '17 at 07:23
  • 1
    more specifically this is a [Built-in magic command](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-matplotlib) – russau Jul 14 '18 at 17:44
  • 1
    @JaakL the plots will render in a new window when using the `agg` backend which is the default in most environments. Ultimately how the plot will render depends on the backend used by matplotlib in that environment. – zr0gravity7 Oct 12 '21 at 16:31
  • 5
    Note that for Google's colab, the matplotlib backend is set to `inline` by default (specifically `module://ipykernel.pylab.backend_inline`). – zr0gravity7 Oct 12 '21 at 16:32
  • None of the responses to OP's question make sense to me. The default behavior (i.e., without using `%matplotlib inline`) is to display plots "inline." I've never in my life encountered a situation where a plot appears in a new window or doesn't appear at all. A plot always, ALWAYS appears below the cell in which it is defined. This feels like a solution to a non-existent problem. What am I missing? – NaiveBae Jul 07 '23 at 16:52
122

To explain it clear:

If you don't like it like this:

enter image description here

add %matplotlib inline

enter image description here

and there you have it in your jupyter notebook.

prosti
  • 42,291
  • 14
  • 186
  • 151
  • 18
    Your second code misses the whole point of using `%matplotlib inline`. The whole point is that now you don't need to use `plt.show()` which you are still using in the second code. One more interesting fact, in your second code, the figure will still appear in the jupyter notebook **even if you don't use** `% matplotlib inline` and just use `plt.show()`. Read my following question [here](https://stackoverflow.com/questions/54329901/behavior-of-matplotlib-inline-plots-in-jupyter-notebook-based-on-the-cell-conten) which is even today unanswered. – Sheldore Jul 17 '20 at 09:26
  • 1
    Yeah, there are certain bugs in the software we use. I usually like to write the clear commands. This means `plt.show()` should exist. The magic of `%matplotlib inline` should also be there even though it may be set somewhere by default. – prosti Jul 17 '20 at 10:11
  • 1
    But I really do not see why you want to use `plt.show()` in your jupyter notebook when you are using matplotlib inline explicitly. Especially, when you are answering a question like this in the context of jupyter notebook – Sheldore Jul 17 '20 at 12:29
  • 1
    I personally like to have a command to control if something should appear or not. I hate being implicit or partial. Imagine the case that someone in error sets `plt.close()` without setting `plt.show()`. You restart the notebook and you see nothing shows up. So I would still set `plt.show()`, it cannot hurt. – prosti Jul 17 '20 at 13:26
  • 7
    Interesting. Because I use Jupyter Notebook and, with or without `%matplotlib inline`, the output is always the second case. Windows never pop out. – Paw in Data Mar 13 '21 at 00:17
  • 1
    @PawinData I have the same experience. It seems that `%matplotlib inline` must be the default setting for more recent versions of Jupyter Notebook – Michael Bergstrom Mar 24 '22 at 08:56
112

Provided you are running IPython, the %matplotlib inline will make your plot outputs appear and be stored within the notebook.

According to documentation

To set this up, before any plotting or import of matplotlib is performed you must execute the %matplotlib magic command. This performs the necessary behind-the-scenes setup for IPython to work correctly hand in hand with matplotlib; it does not, however, actually execute any Python import commands, that is, no names are added to the namespace.

A particularly interesting backend, provided by IPython, is the inline backend. This is available only for the Jupyter Notebook and the Jupyter QtConsole. It can be invoked as follows:

%matplotlib inline

With this backend, the output of plotting commands is displayed inline within frontends like the Jupyter notebook, directly below the code cell that produced it. The resulting plots will then also be stored in the notebook document.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
matusko
  • 3,487
  • 3
  • 20
  • 31
48

If you want to add plots to your Jupyter notebook, then %matplotlib inline is a standard solution. And there are other magic commands will use matplotlib interactively within Jupyter.

%matplotlib: any plt plot command will now cause a figure window to open, and further commands can be run to update the plot. Some changes will not draw automatically, to force an update, use plt.draw()

%matplotlib notebook: will lead to interactive plots embedded within the notebook, you can zoom and resize the figure

%matplotlib inline: only draw static images in the notebook

Yossarian42
  • 1,950
  • 17
  • 14
16

It just means that any graph which we are creating as a part of our code will appear in the same notebook and not in separate window which would happen if we have not used this magic statement.

Arushi Jain
  • 423
  • 4
  • 14
15

TL;DR

%matplotlib inline - Displays output inline


IPython kernel has the ability to display plots by executing code. The IPython kernel is designed to work seamlessly with the matplotlib plotting library to provide this functionality.

%matplotlib is a magic command which performs the necessary behind-the-scenes setup for IPython to work correctly hand-in-hand with matplotlib; it does not execute any Python import commands, that is, no names are added to the namespace.

Display output in separate window

%matplotlib

Display output inline

(available only for the Jupyter Notebook and the Jupyter QtConsole)

%matplotlib inline

Display with interactive backends

(valid values 'GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template')

%matplotlib gtk

Example - GTK3Agg - An Agg rendering to a GTK 3.x canvas (requires PyGObject and pycairo or cairocffi).

More details about matplotlib interactive backends: here


Starting with IPython 5.0 and matplotlib 2.0 you can avoid the use of IPython’s specific magic and use matplotlib.pyplot.ion()/matplotlib.pyplot.ioff() which have the advantages of working outside of IPython as well.

Refer: IPython Rich Output - Interactive Plotting

Ani Menon
  • 27,209
  • 16
  • 105
  • 126
  • Real noob question here, sorry.... what is "IPython kernel" and what is a "magic command". Has Python suddenly split on me and gone non-pythonic? I've never heard of these concepts. – lb_so Jun 07 '20 at 05:49
  • 1
    For a python notebook(ipynb) - a ipython kernal or jupyter kernal is the version of python(and dependencies) to be used by the project. You can start a jupyter notebook and then change kernals to run the cells with a different configuration of python and configure environment variables and much more. – Ani Menon Jun 08 '20 at 11:54
  • 1
    @Ib_so Magic command is a ipython/jupyter feature. [Read more here.](https://ipython.readthedocs.io/en/stable/interactive/magics.html) – Ani Menon Jun 08 '20 at 11:56
12

Starting with IPython 5.0 and matplotlib 2.0 you can avoid the use of IPython’s specific magic and use matplotlib.pyplot.ion()/matplotlib.pyplot.ioff() which have the advantages of working outside of IPython as well.

ipython docs

Vicki B
  • 544
  • 2
  • 9
  • 20
  • I think this is different from changing the backend. Unless backend is `inline`, plots are generated in outer windows and you need to use display() to show them in the notebook. – Vincenzooo May 17 '20 at 08:56
  • Whether it's different than changing the backend, it sure helped me in an ipython terminal while running an x-server. – Ben Ogorek Jan 16 '21 at 15:25
8

If you don't know what backend is , you can read this: https://matplotlib.org/stable/users/explain/backends.html

Some people use matplotlib interactively from the python shell and have plotting windows pop up when they type commands. Some people run Jupyter notebooks and draw inline plots for quick data analysis. Others embed matplotlib into graphical user interfaces like wxpython or pygtk to build rich applications. Some people use matplotlib in batch scripts to generate postscript images from numerical simulations, and still others run web application servers to dynamically serve up graphs. To support all of these use cases, matplotlib can target different outputs, and each of these capabilities is called a backend; the "frontend" is the user facing code, i.e., the plotting code, whereas the "backend" does all the hard work behind-the-scenes to make the figure.

So when you type %matplotlib inline , it activates the inline backend. As discussed in the previous posts :

With this backend, the output of plotting commands is displayed inline within frontends like the Jupyter notebook, directly below the code cell that produced it. The resulting plots will then also be stored in the notebook document.

Wayne
  • 6,607
  • 8
  • 36
  • 93
2

Provided you are running Jupyter Notebook, the %matplotlib inline command will make your plot outputs appear in the notebook, also can be stored.

Ashiq Imran
  • 2,077
  • 19
  • 17
1

I think that with recent versions of Jupyter/matplotlib, the figures are plotted "inline" without the need to use %matplotlib inline.

So one might think that this command is now useless… but to my understanding, it creates a "manager" which configures the plotting parameters. Matplotlib looks for an existing manager when creating a figure, and creates one if necessary. Inside matplotlib.pyplot.figure:

    manager = _pylab_helpers.Gcf.get_fig_manager(num)
    if manager is None:
        # not relevant stuff…
        manager = new_figure_manager(
            num, figsize=figsize, dpi=dpi,
            facecolor=facecolor, edgecolor=edgecolor, frameon=frameon,
            FigureClass=FigureClass, **kwargs)

Now, setting a plotting parameter (rcParams) will not create a "manager" by itself. So when plotting a figure for the first time, a new manager will be created and will overwrite your parameters.

Comment/un-comment the %matplotlib inline and see what happens. (Do not forget to restart the kernel between each try!)

import matplotlib.pyplot as plt
from matplotlib.image import imread
# %matplotlib inline

plt.rcParams["figure.dpi"] = 200
plt.imshow(imread("path_to_your_image"))
print(plt.rcParams["figure.dpi"])
0

In Jupyter Notebook versions earlier than 5.0, the %matplotlib inline command ensures that Matplotlib plots are displayed inline within the notebook, directly below the code cell that produced it. However, you do not need to call plt.show() to display the plots when using %matplotlib inline1. Once you have included the %matplotlib inline command in your code, any Matplotlib plots that you create will be automatically displayed inline within the notebook, without the need for calling plt.show().

Plots display in separate popup windows by default when we call plt.show() without using %matplotlib inline in Jupyter Notebook versions earlier than 5.0.

In Jupyter Notebook ≥ 5.0, --> In Jupyter Notebook versions 5.0 and above, plots automatically display inline(no need to write %matplotlib inline). Using plt.show() or not is optional to display plots.

-2

It is not mandatory to write that. It worked fine for me without (%matplotlib) magic function. I am using Sypder compiler, one that comes with in Anaconda.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62