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

如何将matplotlib(python)窗口保持在后台?,python,matplotlib,background,window,focus,Python,Matplotlib,Background,Window,Focus,我有一个python/matplotlib应用程序,它经常使用来自测量仪器的新数据更新绘图。使用新数据更新绘图时,绘图窗口不应相对于桌面上的其他窗口从背景更改为前景(反之亦然) 在运行Ubuntu16.10和matplotlib 1.5.2rc的机器上,Python 3可以按预期工作。但是,在使用Ubuntu 17.04和matplotlib 2.0.0的另一台机器上,每次使用新数据更新绘图时,图形窗口都会弹出到前面 在使用新数据更新绘图时,如何控制窗口前景/背景行为并保持窗口焦点 下面是一个代

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

在运行Ubuntu16.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)

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

由于我无法以任何方式测试这一点,所以我建议您尝试什么:不要使用
plt.ion()
,如果您使用
plt.show(block=False)
,然后在
while
循环中,在
plt.plot()调用之后添加
plt.draw()
,会发生什么情况?@Thomas Kühn:谢谢您的建议。然而,这并没有改变Ubuntu 17.04/matplotlib 2.0.0环境中的任何东西?也许值得更改一下,看看这是否解决了问题。@Ed Smith:我不知道上面显示的示例代码默认使用哪个后端。但为了确保这一点,我尝试了显式选择TkAgg后端。这并没有改变任何事情。如果您由于使用
时间而出现UI问题,这里有一个解决方法。睡眠
,例如无法移动/调整窗口大小,请查看此答案,这有点像是对
plt.pause
方法的重新实现。如果您只是更新行,不需要其他重新缩放等。,您可以将
plt.pause()
替换为
fig.canvas.flush\u events()
。这是关键的区别如果我能把这个答案标记为有用一百次,我当然会这么做。非常感谢您的代码片段,它工作得非常好:)matplotlib让我非常头疼。。。将Qt用作后端(
matplotlib.use('Qt5Agg')
)时,需要在
flush\u事件调用之前插入
fig.canvas.draw\u idle()
。。。