-
-
Notifications
You must be signed in to change notification settings - Fork 396
Import hooks to set up inline backend when matplotlib is loaded #82
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
Conversation
Addresses ipython/ipython#6424 We believe that most people using matplotlib from a Jupyter frontend want plots to appear inline. Particularly when introducing new users to Python, we end up telling them to run '%matplotlib inline' with a "don't worry about what this does...", which feels wrong when we're trying to help them understand what they're doing. This is an attempt to make inline plots the default when you use matplotlib in an IPython kernel. It installs import hooks to watch for matplotlib being imported, and sets up the inline backend when it is. There is a config option (IPKernelApp.mpl_plots_inline) to disable this behaviour. Specifying a backend with %matplotlib or %pylab should also override it. We've discussed before whether this belongs in IPython or in matplotlib. I don't have a strong preference, but I got the impression that other people preferred it to be in IPython. If we decide to go the other way, I'm happy to help mpl do it.
|
👍 to the idea, but don't you think the default should be the interactive notebook backend? It's really the most powerful way to use matplotlib in a notebook these days and is pretty performant, even over remote connections. (And if it's not performant, it's no worse in functionality than I don't have a strong preference about where this lives. However, I don't like that this creates a second config file location to set the backend in addition to
And then we get rid of any configuration on the Jupyter side. This gives the user one place to set the backend and Jupyter will follow it. |
|
We discussed the possibility of using nbagg before, but I think it only works in a notebook. The inline backend is more basic, but it should work from any Jupyter frontend. I don't want to do it based off the backend already set in mpl, because if you haven't specifically configured a backend, you'll probably get a GUI backend (on my system, the default is TkAgg). The aim is to avoid people having to do configuration to get plots inline. If I was to do this in mpl, I'd add a config option called something like |
Oh, of course. Sorry I missed that.
Considering all that, I suppose that is the best option. A middling alternative is to have the ipython backend setting live in the ipython config but instead of being boolean as proposed here, be "notebook", "inline", "same" or any of the other matplotlib built-in backends. |
|
You can already configure the mpl backend from IPython, but for historical reasons that works by loading mpl as soon as IPython is started, so we haven't set any default value for that. If we do keep this in IPython, I like the idea of it being configurable to any backend on mpl import as well. Do you think this would be better as a feature in matplotlib? It would need some knowledge of IPython to set up the hooks the inline backend relies on. I hope some of the others will weigh in on this too. |
|
Couldn't we tack a rich repr on to nbagg that will fall back to just I am unclear on why anyone would prefer a static figure to an interactive On Thu, Dec 3, 2015, 11:42 Thomas Kluyver [email protected] wrote:
|
|
If nbagg sent a plain png fallback along with the interactive HTML version, I think we'd be happy for that to be the default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the hook on matplotlib makes it impossible for
import matplotlib
matplotlib.use('something')
to work. Is there something else we can look for that wouldn't preempt explicit backend selection? I've used pyplot in my own version of this, but I'm not sure if it's sufficiently general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the only problem is that the import hook loads our backend (and pyplot) in order to set up the config changes and post-execute hooks that the inline backends need. If we can delay that stuff (the call to configure_inline_support()) until the backend is actually loaded, I think it would be fine to set the backend on loading matplotlib, because the setting isn't committed until matplotlib.backends is loaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was also discussion at scipy with @WeatherGod to delay actually forcing the back end until the first figure is created.
|
@tacaswell There are a wide range of applications where in interactive graphic is simply not performant. Large graphs that plot thousands or millions of points can easily be viewed as a static png because the data is far larger than the pixels used to show it. A simple interactive backend like |
|
@cswarth That is not how There can be performance issues inherent to mpl (ex, 1M points in a |
|
Thank you for the correction! I was assuming it was implemented like a number of other SVG-based systems that fail miserably for large data. I should have checked before commenting. |
|
@cswarth: No worries. We haven't done a very good job communicating about how it works -- and it is very different from most other systems. |
|
Reviving this, since I would like to ship 4.3 very soon. Sorry for the long delays. @mdboom @tacaswell is there any module we can put this import detection on that we we can know will trigger automatic backend selection? I'd really like to avoid breaking In my version I detect pyplot, but that's because I always import pyplot. The general logic I'd like: if importing_something_in_matplotlib_would_trigger_backend_selection:
if backend_isnt_already_selected:
%matplotlib inlineSo we need to know:
If we have that, I think we are set and can take care of the rest on our side. |
|
ping @takluyver |
|
I think we were waiting for answers to @minrk's questions, to work out what we can reliably watch for to override automatic backend selection. |
|
Would it be simpler to change the logic to: where |
|
I think that's roughly what we're aiming for already. It's the |
|
There is also talk of deferring the pinning of the backend until you use On Tue, Apr 26, 2016, 08:38 Thomas Kluyver [email protected] wrote:
|
|
Does that seem likely? As part of that change, could you create a 'get the default backend' hook that we could plug into, rather than using import hooks? |
|
I would say that it is likely to happen at some point, but it isn't going On Tue, Apr 26, 2016 at 9:01 AM, Thomas Kluyver [email protected]
|
|
Thanks! I think we've waited long enough for this one that we can wait a few more months, especially since there doesn't seem to be a good way to do it at present. I won't be at SciPy this year, unfortunately, but other IPython people certainly will be. |
|
Closing in favor of the lighter #159. Getting close to this one! |
Addresses ipython/ipython#6424
We believe that most people using matplotlib from a Jupyter frontend want plots to appear inline. Particularly when introducing new users to Python, we end up telling them to run
%matplotlib inlinewith a "don't worry about what this does...", which feels wrong when we're trying to help them understand what they're doing.This is an attempt to make inline plots the default when you use matplotlib in an IPython kernel. It installs import hooks to watch for matplotlib being imported, and sets up the inline backend when it is. There is a config option (
IPKernelApp.mpl_plots_inline) to disable this behaviour. Specifying a backend with%matplotlibor%pylabshould also override it.We've discussed before whether this belongs in IPython or in matplotlib. I don't have a strong preference, but I got the impression that other people preferred it to be in IPython. If we decide to go the other way, I'm happy to help mpl do it.
Ping @mdboom and @tacaswell