Reputation: 185
I recently upgraded to matplotlib 2.1.1 (I was using 1.5 or so before). Now, matplotlib keeps raising figure windows to the foreground. This used to be the case for newly created windows (which makes sense), but now, the windows are brought to foreground whenever pause() is called within a script.
Python 3.6.5 (default, Apr 1 2018, 05:46:30)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.use('TkAgg')
>>> import matplotlib.pyplot as plt
>>> plt.figure()
<matplotlib.figure.Figure object at 0x7fab8c0ace80>
>>> plt.pause(1) # <--- the figure gets created and put into foreground here (this is expected)
>>> plt.pause(1) # <--- the figure gets put into foreground again here (this is undesired)
Strangely, the behaviour changes slightly in other backends. When using qt5, the weird raising behaviour only happens when pause() is executed more than once without an interactive prompt in between:
Python 3.6.5 (default, Apr 1 2018, 05:46:30)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.use('Qt5Agg')
>>> import matplotlib.pyplot as plt
>>> plt.figure()
<matplotlib.figure.Figure object at 0x7fcaeff5de80>
>>> plt.pause(1) # <--- the figure gets created and put into foreground here
>>> plt.pause(1) # <--- the figure stays in background
>>> plt.pause(1); plt.pause(1) # <--- the figure gets put in foreground when the second pause is executed.
Does anybody know how to disable this behaviour? I have an application which frequently updates figures and uses pause. With figures popping up in foreground all the time, the computer becomes completely unusable for any other work.
System: Ubuntu 18.04 (tested using Gnome and Unity) Matplotlib 2.1.1 Python 3.6.5
Upvotes: 1
Views: 253
Reputation: 1158
This issue has annoyed me for many years. It is now very easy to fix thanks to a built-in option:
import matplotlib
matplotlib.rcParams["figure.raise_window"] = False
Upvotes: 0
Reputation: 185
The link ngoldbaum posted and the source code show the problem. Pause is now designed to always raise all figures. Based on this, I was able to create a workaround which avoids using pause() but allows me to update and pause figures as needed.
Two things are needed:
1) Each newly created figure needs to be shown. Otherwise, the window might never show up. Thus, figures are created using the commands
figure = plt.figure()
figure.canvas.manager.show()
2) Effectively the code of pause() without the show() is executed whenever I wasnt to pause:
manager = matplotlib.backend_bases.Gcf.get_active()
if manager is not None:
canvas = manager.canvas
if canvas.figure.stale:
canvas.draw_idle()
canvas.start_event_loop(1)
Here, the argument to canvas.start_event_loop is the duration we want to pause for.
Upvotes: 1