-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Make pyplot.pause not give focus to the figure window #11131
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
Comments
I have recreated an older version of pause import matplotlib
from matplotlib import _pylab_helpers
from matplotlib.rcsetup import interactive_bk as _interactive_bk
def pause(interval):
"""
Pause for *interval* seconds.
If there is an active figure it will be updated and displayed,
and the GUI event loop will run during the pause.
If there is no active figure, or if a non-interactive backend
is in use, this executes time.sleep(interval).
This can be used for crude animation. For more complex
animation, see :mod:`matplotlib.animation`.
This function is experimental; its behavior may be changed
or extended in a future release.
"""
backend = matplotlib.rcParams['backend']
if backend in _interactive_bk:
figManager = _pylab_helpers.Gcf.get_active()
if figManager is not None:
canvas = figManager.canvas
if canvas.figure.stale:
canvas.draw()
plt.show(block=False)
canvas.start_event_loop(interval)
return
# No on-screen figure is active, so sleep() is all we need.
import time
time.sleep(interval) When I use this version of pause, the figure is still brought to the front and given focus, so it seems like the change I noticed is due do some other changes deeper in the matplotlib system. Any ideas? I don't necessarily need any changes to the pause function, I just want a simple way to update/refresh/redraw a figure in a loop without bringing the figure to the front. But it would be nice if that was possible with EDIT: I managed to not have the figure brought to the front by commenting out the line def pause(interval, focus_figure=True):
backend = matplotlib.rcParams['backend']
if backend in _interactive_bk:
figManager = _pylab_helpers.Gcf.get_active()
if figManager is not None:
canvas = figManager.canvas
if canvas.figure.stale:
canvas.draw()
if focus_figure:
plt.show(block=False)
canvas.start_event_loop(interval)
return
# No on-screen figure is active, so sleep() is all we need.
import time
time.sleep(interval) But I am no matplotlib expert, so I don't know what side effects removing the call to |
The underlying problem is how to control both raise and focus behavior on each of the backends and for every platform and window manager. One might expect each gui backend to have a simple API for doing this, but it seems not be be the case at all. I think what you are running into is #6384. The problem that was addressing was the tendency for Qt windows to come up behind other windows, so there was no indication that a plot had been made. But I completely understand the opposite problem, of a plot popping up on top of something when that is not what you want. What we might be able to do is give each backend FigureManager a |
Can you please revert the change to pause? Windows should never steal focus just to fix them popping up in the background - the reason they pop up in the background is due to the window manager choosing to keep focus on the application the user is currently working with. This change is incredibly disruptive, we also have multiple windows refreshing continuously and are unable to work with this change. |
Just adding support to reverting the behavior. I have found this change breaks my default development environment. I used to start a job running with interactive plots updating and then move to another Ubuntu workspace to check email or work on the script in another window, etc. Now I can't do any of this because the plot window is constantly stealing focus. For now I have reverted to 2.0.2, but please consider reverting this change. |
Maybe it's worth noting that In case people want to run some continuous loop in the background, one would rather use either the provided |
I use plt.pause mostly in the interactive mode for doing quick and dirty first tests before I build something more sophisticated. So please make it choose-able by the users! |
I add to the request: I want to plot stuff in an interactive (zoomable etc) window but still be able to use my terminal the program is executed in. It is impossible if window is stealing the focus. This is not at all a minor problem. |
Within an interactive python/IPython session or from the operating system shell? If the latter you just put the python invocation in the background. If the former, I don’t think that’s possible. |
@jklymak |
…Make pyplot.pause not give focus to the figure window
@ImportanceOfBeingErnest That's a false assumption. For example, I might be running a simulation in the background and want to see what it looks like every now and then. That doesn't mean I want the window popping up repeatedly in front of everything else. This behaviour is very annoying. |
Second @carlosgmartin statement. In my case I'm interacting with one figure and updating plots in a second figure and I don't want that second figure to steal focus every time it updates. |
Hopefully #15440 will make this easier to control (by providing the relevant snippets for all toolkits). |
I did find a workaround for at least my case: let the other figure window steal focus but set it back programmatically with
where |
I mean, you can always replace
if in interactive mode ( |
Bingo, thank you |
Closed by #15440. |
@ImportanceOfBeingErnest Is the first line necessary? It seems to work with the second line alone. |
The |
Bug report
Bug summary
I'm using
matplotlib.pyplot.pause()
to update a plot in a loop, mostly for debugging purposes. On my old matplotlib version (maybe 2.0.2, not sure) this worked fine, but after updating to 2.2.2 the pause function seems to have changed behaviour. Previously the figure window was left in the background, but now it is brought to the front and given focus. This makes hit hard to cancel the running script (Ctrl+C in Jupyter QtConsole), which I often use while debugging a script.I know it is noted in the docs of pause that "This function is experimental; its behavior may be changed or extended in a future release.", but is there any way to bring back the old behaviour? Perhaps via a argument
focus_window=False
or something like that?Code for reproduction
Matplotlib version
The text was updated successfully, but these errors were encountered: