今日、私はmatplotlibをバージョン2.0.2にアップグレードしましたが、おそらく3年間アップグレードしませんでした。
これで、インタラクティブプロットではウィンドウが常に前面に表示されるという問題があります。これは、ここで matplotlibプロットウィンドウをアクティブウィンドウとしてポップアップ表示する がデフォルトの動作になったかのようです。
どうすれば無効にできますか? 5秒ごとにウィンドウが前面に表示されて、テキストエディター、ブラウザーなどが表示されないようにしたい...
アクティブウィンドウの前面または背面のどちらに配置しても、配置したZオーダーのままにしておきます。
2016年1月31日の次のコミットがこの問題のある動作の原因であると思います: tkagg:それぞれの新しいウィンドウを上げる;部分的に#596に対処
Githubに関連するコメントが見つかりました https://github.com/matplotlib/matplotlib/issues/596#issuecomment-305298577
この問題を引き起こしているのはplt.pause
への私の呼び出しであり、plt.plot
の呼び出しではないようです。
この問題は、Tk
バックエンドを使用した場合にのみ発生するようです。 Qt
バックエンドを使用すると、ウィンドウは、_plt.pause
_で更新しているときと同じ場所にとどまります。
バックエンドを変更するには、スクリプトの先頭でこれらの行を使用します。
_import matplotlib
matplotlib.use("Qt4agg") # or "Qt5agg" depending on you version of Qt
_
plt.pause
_の変更バックエンドを変更できない場合は、次の方法が役立つことがあります。ウィンドウが常に前面にポップアップする原因は、_plt.pause
_が内部でplt.show()
を呼び出すことにあります。したがって、pause
を呼び出さずに、独自のshow
関数を実装します。これは、最初にplt.ion()
をインタラクティブモードにしてから、少なくとも1回はplt.show()
を呼び出す必要があります。その後、以下に示すように、カスタムmypause
関数を使用してプロットを更新できます。
_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)
_
animation
を使用します。最後に、_matplotlib.animation
_クラスを使用すると、上記のすべてが廃止されます。 _matplotlib.animation.FuncAnimation
_の例を示します matplotlibページ 。
Macでも同じ問題が発生しました。これが最善の方法かどうかはわかりませんが、plt.pause(0.001)
を使用する代わりに、fig.canvas.start_event_loop(0.001)
に切り替えて、アニメーションの各フレームを更新しました。これにより、ウィンドウをバックグラウンドに留めることができます。
これは2019年4月で、Matplotlib 3.0.3のmypause()関数(最新のpyplot実装からコピー)は次のようになります。
import time
import matplotlib.pyplot as plt
def mypause(interval):
manager = plt._pylab_helpers.Gcf.get_active()
if manager is not None:
canvas = manager.canvas
if canvas.figure.stale:
canvas.draw_idle()
#plt.show(block=False)
canvas.start_event_loop(interval)
else:
time.sleep(interval)
いくつかのテスト(Qt5バックエンド/ Spyder/Windows 7 64ビット)の後、私にとってトリックとなる呼び出しは次のとおりです。
#plt.pause(0.001) #Brings plot to foreground
#fig.canvas.draw() #Does not work
#plt.draw_all() #Does not work
#plt.draw() #Does not work
#fig.canvas.flush_events() #Updates only if I click the figure
#import time; time.sleep(0.001) #Does not help flush_events()
#fig.canvas.draw_idle() #Does not work by itself
#fig.canvas.start_event_loop(0.001) #Does not work by itself
#mypause(0.001) #Works!
#Works!
fig.canvas.draw_idle()
fig.canvas.start_event_loop(0.001)
イチジクはあなたのフィギュアオブジェクトでした。私の場合、どちらも単独では機能しませんでした。 animation のドキュメントによると、これは本質的にFuncAnimationが行うことです。
このドキュメントページの助けを借りて、matplotlib.animation
を使用するようにコードを書き直しました https://matplotlib.org/devdocs/api/animation_api.html#module-matplotlib.animation
私はこのページからそのページに到達しました https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.pause.html
matplotlib.pyplot.pause
について次のように述べています
これは粗雑なアニメーションに使用できます。より複雑なアニメーションについては、matplotlib.animationを参照してください。
この関数は実験的です。その動作は将来のリリースで変更または拡張される可能性があります。