python/matplotlibアプリケーションがあり、測定機器からの新しいデータでプロットを頻繁に更新します。プロットウィンドウは、他のウィンドウに対してバックグラウンドからフォアグラウンドに(またはその逆に)変更しないでください。プロットが新しいデータで更新されたときのデスクトップ上のウィンドウ。
これは、matplotlib1.5.2rcを搭載したUbuntu16.10を実行しているマシンでPython 3を使用すると、希望どおりに機能しました。ただし、Ubuntu17.04とmatplotlib2.0.0を搭載した別のマシンでは、図ウィンドウが前面に表示されます。プロットが新しいデータで更新されるたび。
新しいデータでプロットを更新するときに、ウィンドウの前景/背景の動作を制御し、ウィンドウのフォーカスを維持するにはどうすればよいですか?
これが私のプロットルーチンを説明するコード例です:
import matplotlib
import matplotlib.pyplot as plt
from time import time
from random import random
print ( matplotlib.__version__ )
# set up the figure
fig = plt.figure()
plt.xlabel('Time')
plt.ylabel('Value')
plt.ion()
# plot things while new data is generated:
t0 = time()
t = []
y = []
while True:
t.append( time()-t0 )
y.append( random() )
fig.clear()
plt.plot( t , y )
plt.pause(1)
matplotlibがバージョン1.5.2rcから2.0.0に変更され、pyplot.show()がウィンドウを前面に表示します( ここ を参照)。したがって、重要なのは、ループ内でpyplot.show()
を呼び出さないようにすることです。 pyplot.pause()
についても同じことが言えます。
以下は実際の例です。これにより、最初はウィンドウが前面に表示されます。ただし、ユーザーはウィンドウを背景に移動することができ、図が新しいデータで更新されてもウィンドウはそこにとどまります。
この例に示すプロットを作成するには、matplotlibアニメーションモジュールが適している場合があることに注意してください。ただし、インタラクティブプロットでアニメーションを機能させることができなかったため、他のコードのそれ以上の実行がブロックされます。そのため、実際のアプリケーションでアニメーションモジュールを使用できませんでした。
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import time
from random import random
print ( matplotlib.__version__ )
# set up the figure
plt.ion()
fig = plt.figure()
ax = plt.subplot(1,1,1)
ax.set_xlabel('Time')
ax.set_ylabel('Value')
t = []
y = []
ax.plot( t , y , 'ko-' , markersize = 10 ) # add an empty line to the plot
fig.show() # show the window (figure will be in foreground, but the user may move it to background)
# plot things while new data is generated:
# (avoid calling plt.show() and plt.pause() to prevent window popping to foreground)
t0 = time.time()
while True:
t.append( time.time()-t0 ) # add new x data value
y.append( random() ) # add new y data value
ax.lines[0].set_data( t,y ) # set plot data
ax.relim() # recompute the data limits
ax.autoscale_view() # automatic axis scaling
fig.canvas.flush_events() # update the plot and take care of window events (like resizing etc.)
time.sleep(1) # wait for next loop iteration