简体   繁体   English

如何在matplotlib中以交互模式移动图形窗口?

[英]How to move figure window in interactive mode in matplotlib?

I'm trying to monitor real-time data with matplotlib. 我正在尝试用matplotlib监控实时数据。

I found that I can update plot dynamically with interactive mode in Pyplot. 我发现我可以在Pyplot中使用交互模式动态更新绘图。

And it worked well, but one problem is 'I cannot manipulate the figure window at all'. 它运作良好,但有一个问题是“我根本无法操纵数字窗口”。 For example, move or re-size the figure window. 例如,移动或重新调整图形窗口的大小。

Here is my code. 这是我的代码。

This is cons of interactive mode? 这是互动模式的缺点? or I'm using it incorrectly? 或者我使用不正确?

import matplotlib.pyplot as plt
import time
import math

# generate data
x = [0.1*_a for _a in range(1000)]
y = map(lambda x : math.sin(x), x)

# interactive mode
plt.ion() # identical plt.interactive(True)

fig, ax = plt.subplots()
# ax = plt.gca()
lines,  = ax.plot([], [])

# ax.set_ylim(-1, 1)
ax.grid()

MAX_N_DATA = 100
x_data = []
y_data = []
for i in range(len(x)):
    # New data received
    x_data.append(x[i])
    y_data.append(y[i])

    # limit data length
    if x_data.__len__() > MAX_N_DATA:
        x_data.pop(0)
        y_data.pop(0)

    # Set Data
    lines.set_xdata(x_data)
    lines.set_ydata(y_data)

    # The data limits are not updated automatically.
    ax.relim()
    # with tight True, graph flows smoothly.
    ax.autoscale_view(tight=True, scalex=True, scaley=True)

    # draw
    plt.draw()
    time.sleep(0.01)

Thank you. 谢谢。

As shown in this answer to another question , replace plt.draw() with plt.pause(0.05) . 另一个问题的答案所示,用plt.pause(0.05)替换plt.draw() plt.pause(0.05) This solved the problem for me. 这解决了我的问题。

Although I still think you should use bokeh, I'll tell you how to do it with matplotlib. 虽然我仍然认为你应该使用散景,但我会告诉你如何用matplotlib来做。

The problem why it won't work ist that matplotlib's event loop is not active and therefore it cannot digest window events (like close or resize). 它无法工作的问题是matplotlib的事件循环不活动,因此无法消化窗口事件(如关闭或调整大小)。 Unfortunately it is not possible to trigger this digestion from the outside. 不幸的是,不可能从外部引发这种消化。 What you have to do is to use matplotlib's animation system. 你要做的是使用matplotlib的动画系统。
Your code is actually quite well prepared for it so you can use FuncAnimation . 您的代码实际上已做好充分准备,因此您可以使用FuncAnimation

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import math

# generate data
x = [0.1*_a for _a in range(1000)]
y = map(lambda x : math.sin(x), x)

# don't need ion, we're using block=True (see end of code)

fig, ax = plt.subplots()
fig.show()
# ax = plt.gca()
lines,  = ax.plot([], [])

# ax.set_ylim(-1, 1)
ax.grid()

MAX_N_DATA = 100
x_data = []
y_data = []

def showdata(i):

    # New data received
    x_data.append(x[i])
    y_data.append(y[i])

    # limit data length
    if x_data.__len__() > MAX_N_DATA:
        x_data.pop(0)
        y_data.pop(0)

    # Set Data
    lines.set_xdata(x_data)
    lines.set_ydata(y_data)

    # The data limits are not updated automatically.
    ax.relim()
    # with tight True, graph flows smoothly.
    ax.autoscale_view(tight=True, scalex=True, scaley=True)

    # draw will be called by the animation system

# instead of time.sleep(0.01) we use an update interval of 10ms
# which has the same effect
anim = FuncAnimation(fig, showdata, range(len(x)), interval=10, repeat=False)

# start eventloop
plt.show(block=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM