Skip to content

BUG: interactive mode is disabled by default #11283

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

Closed
mspacek opened this issue May 22, 2018 · 15 comments
Closed

BUG: interactive mode is disabled by default #11283

mspacek opened this issue May 22, 2018 · 15 comments

Comments

@mspacek
Copy link
Contributor

mspacek commented May 22, 2018

I just taught a very frustrating Python data analysis class where I introduced matplotlib for the first time. Nearly all of the students are using the latest Anaconda on their system, either for windows or mac. For all of them, interactive mode was disabled by default: plotting anything in regular IPython (I'm avoiding Jupyter notebook for various reasons) resulted in a disappointing whole lotta nothing for each and every one of them. Sure, they can do plt.ion(), or failing that plt.show(), but why the hassle?

After grappling with where exactly Anaconda stores its particular copy of the matplotlibrc file, uncommenting the #interactive : False line and setting it to True worked for every single student. No back-end issues crept up. This was on a very diverse set of systems. I believe the backends included macosx and on windows probably Qt5.

Since it works by default, why isn't interactive mode enabled by default in matplotlib? Other than its non-standard location for the matplotlibrc file, I don't think Anaconda is at fault here. I think Anaconda is simply inheriting the default setting from matplotlib. Everyone in the class was using the Anaconda 5.1 for Python 3.6.

It's sad and embarrassing that in 2018, after installing a huge package that is supposed to be the one-stop solution for beginners on all major platforms, a simple plt.plot([1, 2, 3]) does absolutely nothing by default. It makes MATLAB look snazzy in comparison.

@tacaswell
Copy link
Member

Because defaulting to interactive mode is very disruptive what using Matplotlib in scripts or any any context which is not the prompt.

To got proper interaction working you also need to set up the InputHook (see #4779 for lots of details) properly. With up-to-date Matplotlib + IPython we arrange for that to happen if we are imported within IPython, but that is not always the case leading to the just as frustrating "my window came up but it was dead" issue.

I think setting the rcparam for interactive to be true is a bad idea, either type %matplotlib in IPython (this is what I do) or put the import in your IPython start up files.

@WeatherGod
Copy link
Member

WeatherGod commented May 22, 2018 via email

@tacaswell
Copy link
Member

An interesting idea (that I just had) is to get IPython to import plt and inject it into the user namespace in the magic....

@mspacek
Copy link
Contributor Author

mspacek commented May 22, 2018

I don't understand. What are these cases when interactive mode is disruptive? Why wouldn't you want interactive mode in a script? When you only want to dump figures to disk and not look at them? Surely that situation is less frequent, and is something a power user generating heaps of figures would do, not a beginner. In which case, the power user is much better suited to manually disable interactive mode in his or her script if it really is a problem.

I think setting the rcparam for interactive to be true is a bad idea, either type %matplotlib in IPython (this is what I do) or put the import in your IPython start up files.

The question comes down to are we throwing unnecessary roadblocks in the way of beginners, those least able to change their defaults? I think we are. It's been so long since I used %matplotlib, I had to look it up. I've had interactive : True in my matplotlibrc forever, and I'm always astonished when I see others struggling with what to me is a problem from the previous decade. As @tacaswell suggests, maybe the solution might be to change some default setting in IPython instead of MPL? Would that be more palatable (for reasons I don't understand)?

@mspacek
Copy link
Contributor Author

mspacek commented May 22, 2018

@WeatherGod wrote:

This is standard operating procedure for everyone giving a tutorial to use %matplotlib for ipython

For me, the big question is "why?"

@ImportanceOfBeingErnest
Copy link
Member

I would find it rather annoying to have some window pop up simply by typing any plotting command.

But in any case, the normal use case of python is still to be run as scipts. As long as this is the case, you don't want interactive mode turned on by default, because that would result in no plotting window being shown at all even on plt.show(); while in IPython you may still simply call plt.show() to get the winow pop up - appart from the usual solutions mentionned above, like %matplotlib.

@tacaswell
Copy link
Member

@mspacek Please read #4779 for why.

Please remember that Matplotlib is used in many different ways in many different contexts your exact use case is not the only one we need to support.

@mspacek
Copy link
Contributor Author

mspacek commented May 22, 2018

Ah, plain Python vs IPython. OK, interactive mode in plain Python is a problem, I understand that. But that just punts the question to why run scripts that plot stuff in plain Python instead of IPython? Is that really still the most common use case? I imagine most people these days use run myscript.py in IPython or Jupyter. I seriously doubt this is just my particular use case.

I looked at the changes in #4779. There's a lot of nitty gritty in there indeed, but I'm afraid those docs don't explain to me why the default is the way it is, especially when that default has the opposite behaviour of matlab. Would it be possible for MPL to check if the right inputhook exists (i.e., it's being launched in IPython instead of plain Python)? Or would it be possible for IPython to simply turn interactive mode on by default?

@mspacek
Copy link
Contributor Author

mspacek commented May 22, 2018

Also, it's not just a matter of telling beginners to run %matplotlib at the start of every session. What if they aren't being tutored at all, and are trying to figure it out on their own? They're the least qualified users to do so, which can take an incredible amount of time, or simply end with failure.

@WeatherGod
Copy link
Member

WeatherGod commented May 22, 2018 via email

@ImportanceOfBeingErnest
Copy link
Member

There is a passage somewhere in that guide that explains that it is inefficient to draw a figure several times - hence the default is to defer drawing until you explicitely ask for it.

All examples on the matplotlib page have plt.show() in them. It should be pretty self-explanatory. Even for new users. If new users cannot google something like "matplotlib doesn't show plot in ipython", they shouldn't be using a computer. (But of course matplotlib can work towards letting its own explanation of things appear in such search.)

Even in IPython I wouldn't want interactive mode to be turned on by default, because if you run myscript.py you would usually want the script to run as a whole before being presented the final figure(s) on screen.

You may configure IPython to run some commands at startup, see e.g. here.

It seems the shell tutorial is completely out of date and needs to be updated to include the common use cases. #4779 seems a good way of doing this so I wonder what caused it to lie around for over two years without being finished/merged?

@jklymak
Copy link
Member

jklymak commented May 22, 2018

I'll be a bit pedantic, and suggest that a tutorial should teach good practice, and interactively typing at a command prompt is not good practice because its too easy to lose your work. Notebooks or scripts let you keep a record of what you have done, and refinement is at least as easy as on the command line, if not easier.

@fredrik-1
Copy link
Contributor

I mostly use spyder when ploting and the interactive ploting is the default (or maybe inline but the other backends are interactive by default).

It is clear that interactive ploting might result in a performance drawback for complicated plots when adding commands on the command line one and one but it is really a drawback if ploting with scripts?

I have tried to test this and couldn't find any large difference in performance (but the low memory and other bad things with the computer I used might have fooled me) and it would make sense that if event loop just plot when the calculations are finished.

I have not really thought this through before and I am curious if I could have run my quite large and complicated plotting scripts much faster without using interactive mode.

@fredrik-1
Copy link
Contributor

I would find that the inconsistency between the behavior of matplotlib in
ipython with ion turned on by default and then not for non-ipython
situations would be much more confusing for beginners progressing to more
general coding and development practices.

I realize that this is actually what have happened to me because of the defaults in spyder. Yes, I find this quite confusing when thinking about it now but I believe that it was best when spyder worked as I expected without any extra work when I was new to python and matplotlib and that I need to do some extra work now to really understand what is going on.

I still find this confusing though and a more up to date documentation would certainly help where it is clear what the functions do and what is supposed to work and what is not supposed to work. Interactive plotting does for example not work for me in standard python (and 4-5 years old posts on github suggest that it is not supported and a mere a coincidence if it works).

Are %matplotlib even included in the matplotlib documentation somewhere?
https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.show.html#matplotlib.pyplot.show

I don't even know the meaning of pylab mode except that it shouldn't be used. I got that behavior when using %matplotlib and setting plt.ioff()

@tacaswell
Copy link
Member

There has been improvement over the past 4 years and now when we detect that pyplot is imported in IPython and a GUI backend is switched to, we will ask IPython to install the correct input hook.

The default default of rcParams['interactive'] needs to stay as False (way too much work / disruption to change that), but because it is in rcparams, users can set it to be True if they wish.

I am going to close this with no action.

@tacaswell tacaswell closed this as not planned Won't fix, can't repro, duplicate, stale May 23, 2022
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

6 participants