Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
449 views
in Technique[技术] by (71.8m points)

python - Make interactive matplotlib window not pop to front on each update (Windows 7)

Today I upgraded matplotlib to version 2.0.2, after not upgrading for possibly 3 years.

Now I have the problem that in interactive plots the window always comes to the front, as if this here make matplotlib plotting window pop up as the active one had come to be the default behaviour.

How can I deactivate it? I don't want the window to come to front every 5 seconds and raise over my text editor, browser, ...

I want it to stay in the z-ordering where I've placed it, be it to front or behind an active window.

I believe that the following commit from 31 Jan 2016 is responsible for this problematic behaviour: tkagg: raise each new window; partially addresses #596

Found a related comment on Github https://github.com/matplotlib/matplotlib/issues/596#issuecomment-305298577

it appears that it is my call to plt.pause which is causing this issue, and not the plt.plot call.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Changing the backend

The issue seems only present using the Tk backend. Using the Qt backend, the window would stay where it was while updating with plt.pause.

To change the backend use those lines at the beginning of your script.

import matplotlib
matplotlib.use("Qt4agg") # or "Qt5agg" depending on you version of Qt

Modifying plt.pause

If changing the backend is not an option, the following might help. The cause of the window constantly popping up to the front comes from plt.pause calling plt.show() internally. You therefore implement you own pause function, without calling show. This requires to be in interactive mode plt.ion() first and then at least once call plt.show(). Afterwards you may update the plot with the custom mypause function as shown below.

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from time import time
from random import random

plt.ion()
# set up the figure
fig = plt.figure()
plt.xlabel('Time')
plt.ylabel('Value')

plt.show(block=False)

def mypause(interval):
    backend = plt.rcParams['backend']
    if backend in matplotlib.rcsetup.interactive_bk:
        figManager = matplotlib._pylab_helpers.Gcf.get_active()
        if figManager is not None:
            canvas = figManager.canvas
            if canvas.figure.stale:
                canvas.draw()
            canvas.start_event_loop(interval)
            return


t0 = time()
t = []
y = []
while True:
    t.append( time()-t0 )
    y.append( random() )
    plt.gca().clear()
    plt.plot( t , y )
    mypause(1)

Using an animation.

Finally, using a matplotlib.animation class would render all of the above obsolete. An example for matplotlib.animation.FuncAnimation is shown on the matplotlib page.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...