【问题标题】:How to move figure window in interactive mode in matplotlib?如何在 matplotlib 中以交互模式移动图形窗口?
【发布时间】:2017-05-18 15:18:15
【问题描述】:

我正在尝试使用 matplotlib 监控实时数据。

我发现我可以在 Pyplot 中使用交互模式动态更新绘图。

它运行良好,但一个问题是“我根本无法操作图形窗口”。例如,移动或调整图形窗口的大小。

这是我的代码。

这是交互模式的缺点?还是我使用不正确?

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)

谢谢。

【问题讨论】:

  • matplotlib 不太适合实时可视化...我建议查看bokeh

标签: python matplotlib


【解决方案1】:

this answer to another question所示,将plt.draw()替换为plt.pause(0.05)。这解决了我的问题。

【讨论】:

    【解决方案2】:

    虽然我仍然认为你应该使用散景,但我会告诉你如何使用 matplotlib。

    它无法工作的问题在于 matplotlib 的事件循环未激活,因此它无法消化窗口事件(如关闭或调整大小)。不幸的是,不可能从外部触发这种消化。你要做的就是使用matplotlib的动画系统。
    您的代码实际上已经为此做好了充分的准备,因此您可以使用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)
    

    【讨论】:

    • 谢谢。但似乎这种解决方法对我不起作用。正如我所提到的,我必须绘制 实时 数据。因此,当我调用drawshow 时,我没有要绘制的完整数据集。而是随着时间的推移累积并动态绘制
    • 我会检查散景。谢谢:D
    • @JaeJunLEE 抱歉完全忘记了这一点:D 好吧,第三个参数range(len(x)) 可以是生成showdata 的数据的生成器。如果此生成器从队列或其他填充了实际计算结果的缓冲区中获取数据,那么您将获得所需的数据。您还可以查看the code 了解我的实时峰值图。它使用多处理来避免 matplotlibs 仅主线程问题。当您取消注释 import nest 时,它应该与随机示例一起运行。
    猜你喜欢
    • 2014-06-17
    • 1970-01-01
    • 2013-07-24
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    相关资源
    最近更新 更多