Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"%matplotlib notebook" required before *every* call to plot? #4879

Closed
ianozsvald opened this issue Aug 7, 2015 · 14 comments
Closed

"%matplotlib notebook" required before *every* call to plot? #4879

ianozsvald opened this issue Aug 7, 2015 · 14 comments

Comments

@ianozsvald
Copy link

The behaviour of "%matplotlib notebook" is different to "%matplotlib inline", I've attached a screenshot, can you help me figure out if this is my machine or if I'm doing something silly? I am expecting both magics to produces similar behaviour. I've seen this issue over the last few months in bigger Notebooks and I figured I had other problems but now I've narrowed it down to just the simple case outlined below.

The problem:

%matplotlib inline in a Notebook causes plots to be shown as static images, only 1 call to %matplotlib inline is required.

%matplotlib notebook in a Notebook enables some interactive features. I have to call this before every plot otherwise I get a non-rendered object in return.

Here I only use %matplotlib notebook. The second plot is not rendered. For the third plot I force another call to %matplotlib notebook and the third image is rendered.

mpl_notebook_bug_onlynotebook

Here I first use %matplotlib inline and then %matplotlib notebook. The final plot (second for notebook) doesn't render:

mpl_notebook_bug

I'm using:

  • Linux Mint 17.2 (Ubuntu 14.04) 64bit
  • Python 3.4.3 (Anaconda 64 bit)
  • IPython 3.2 and Notebook 3.2.0-8b0eef4
  • matplotlib 1.4.3

Maybe I'm being foolish and the point of %matplotlib notebook is to only allow 1 plot to be interactive, so you have to choose which one? And then after switch back to %matplotlib inline?

Any thoughts to clear up my muddled mind would be gladly received. i.

@jenshnielsen
Copy link
Member

At the moment the interactive figure in the nbagg backend is designed to work like a regular interactive GUI figure (QT,GTK etc) so each call to plot will plot in the latest active figure if a figure exists or otherwise create a new one. Therefore you end up with two two identical lines on top of each other in your first example. I'm not sure if this is the right solution since you are effectively plotting in the output of another cell which may be confusing. There is an issue with when the figure is closed i.e. #4841 which may be related.

At the moment the solution is to explicitly create a new figure when you want one.

plt.figure()
plt.plot([1,2,3])
...

Personally I tend to prefer the OO interface.

fig, ax = plt.subplots(1,1)
ax.plot()
ax.set_xlabel('foo')
...

While somewhat more verbose it makes the intend more obvious.
We are working on replacing our properties with Traitlets in #4762
which will allow us to get rid of the verbose getters and setters in the OO interface.

@ianozsvald
Copy link
Author

@jenshnielsen Aha! I hadn't tried plt.figure() before each new plot, I got used to how you didn't have to do that with %matplotlib inline. Thanks for the clarification.

@WeatherGod
Copy link
Member

Another way to look at it is that the inline backend effectively closes the
figure object after executing each cell, while the notebook backend leaves
the figure object open. In regular matplotlib scripting, that means that
any subsequent plotting calls keeps going to that open figure in the
notebook backend, but in the inline, a new figure is automatically created.

We have had "bug reports" going both ways now. In an early iteration of the
notebook backend, we had some people complain that they couldn't update an
existing figure, so we fixed that issue. I think the current behavior is
correct, but requires some more education or maybe some more visual cues of
what is happening. Maybe the figure title bar flashes or something?

On Fri, Aug 7, 2015 at 6:03 AM, Ian Ozsvald notifications@github.com
wrote:

@jenshnielsen https://github.com/jenshnielsen Aha! I hadn't tried
plt.figure() before each new plot, I got used to how you didn't have to
do that with %matplotlib inline. Thanks for the clarification.


Reply to this email directly or view it on GitHub
#4879 (comment)
.

@ianozsvald
Copy link
Author

@WeatherGod I've not found any official docs on %matplotlib notebook, just refs on reddit and the like, hence never being very sure about how it was supposed to work. Is there an official doc explaining it somewhere?

@mpacer
Copy link

mpacer commented Dec 29, 2016

I would like to reiterate a need for further information about the notebook interactive backend.
Eventually I ended here after getting into a recursion where ipython docs point to general matplotlib docs and the most relevant matplotlib docs pointing back to the original python docs. The notebook backend is almost absent from the current docs(excepting a reference in the changelog to a feature that works with %matplotlib notebook as one example of an interactive backend). I believe this could be different in the 2.0 docs, but I didn't see any prs specifically addressing this issue, which even though it's closed was the best resource I could find using a nontrivial amount of time to search with the aim of looking into jupyter/nbconvert#503, since I realized that inline and notebook were jupyter specific and began diving into their respective apis.

@David-OConnor
Copy link

This should be an option. Maybe specify %matplotlib notebook vs %matplotlib notebook-overwrite ?

@jasongrout
Copy link

Note that there is one other notebook-specific way to display plots now - the ipympl widget.

@David-OConnor
Copy link

David-OConnor commented Mar 2, 2017

Thx. I made a module that thinly wraps MPL's plotting functions; uses syntax like plt.plot(...), but does it with fig/ax objects so it works with notebook; I just import it instead of pyplot when using notebooks. Feels hacky, but haven't found a better option.

@AstroMike
Copy link

If you have a long notebook with multiple plots, you certainly don't want to be scrolling all the way back up to the first cell to see your output ...

Personally I much prefer the %matplotlib inline behaviour, although the actual plots in %matplotlib notebook look a lot nicer.

We have had "bug reports" going both ways now. In an early iteration of the
notebook backend, we had some people complain that they couldn't update an
existing figure, so we fixed that issue. I think the current behavior is
correct, but requires some more education or maybe some more visual cues of
what is happening. Maybe the figure title bar flashes or something?

@jklymak
Copy link
Member

jklymak commented Sep 3, 2018

We have a strong preference for the object-oriented API. So each new figure starts with either plt.figure or plt.subplots. I don’t think there is much appetite for changing this so that plt.plot makes a new figure. Indeed there are perfectly valid reasons to want a new cell to operate on an old figure and the current paradigm allows that.

@AstroMike
Copy link

Personally, I would still like to see at least an option where, as with %matplotlib inline, the "backend effectively closes the figure object after executing each cell" (as Weathergod commented above). I use notebooks primarily for teaching, and students find this behaviour more natural/intuitive.

@ImportanceOfBeingErnest
Copy link
Member

I am a bit surprised by the fact that indeed a call to plt.plot in a new cell updates the existing plot. There is of course the option to first close the previous figure via plt.close() or the
image button in the upper corner.

For the inline backend there is a configuration

 %config InlineBackend.close_figures

This option is set to True by default, which means figures are closed at the end of each cell. I am not aware of any such options for the notebook backend, but that would probably be a useful addition.

@kaloatanasov
Copy link

Hi all, although this discussion is closed, I would like to share a video by professor Christopher Brooks getting into some details why to use "%matplotlib notebook," as well as a paper on what's behind matplotlib in general (going through the different layers):

Video: https://www.coursera.org/lecture/python-plotting/matplotlib-architecture-bQ4Ld
Paper: http://www.aosabook.org/en/matplotlib.html

@bombs-kim
Copy link
Contributor

@kaloatanasov I watched the video, but I didn't speak the reason why to use "%matplotlib notebook". He simply said that he will use `"%matplotlib inline" for his class. Where can I exactly find the reason?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests