如何在后台保持matplotlib(python)窗口?

mbr*_*nwa 8 python background focus window matplotlib

我有一个python/matplotlib应用程序,经常使用来自测量仪器的新数据更新绘图.使用新数据更新绘图时,绘图窗口不应相对于桌面上的其他窗口从背景更改为前景(反之亦然).

这在运行Ubuntu 16.10和matplotlib 1.5.2rc的机器上运行Python 3.但是,在使用Ubuntu 17.04和matplotlib 2.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)
Run Code Online (Sandbox Code Playgroud)

mbr*_*nwa 10

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
Run Code Online (Sandbox Code Playgroud)

  • 如果您只是更新行而无需其他缩放,等等,您可以将`plt.pause()`替换为`fig.canvas.flush_events()`。这是关键的区别 (2认同)