首页 > 解决方案 > 如何更新子图?

问题描述

我需要绘制许多图,查看它们并按“y”或“n”。我无法让 matplotlib 在循环中一个接一个地显示图。循环必须向我展示一个情节,然后我将按下某个按钮并重新开始。我现在的代码是:

def press_event(event):
    answer = event.key
    if answer=='y':
        pass
    sys.stdout.flush()
    print(answer)
    
files = os.listdir(folder)

fig, ax = plt.subplots(14,2, figsize=(10,30))
fig.canvas.mpl_connect('key_press_event', press_event)
for file in files:
    target = file
    data = pd.read_csv(folder + target)
    fig.suptitle(target, fontsize=30)
    r = 0
    for key in data:
        sample = data[key]
        ts = [sample[i+1] - sample[i] for i in range(len(sample)-1)]
        decs,ts,point = cusum(sample,10)
        ax[r,0].plot(sample)
        ax[r,0].axvline(point,color='red')
        ax[r,1].plot(decs)
        ax[r,1].axvline(point, color='red')
        r += 1
    plt.show()
    fig.canvas.draw()
    plt.waitforbuttonpress()
    plt.pause(0.1)
    fig.clear()

现在它向我展示了第一个情节。我按下一个按钮,下一个窗口是空白的,内核崩溃了。

标签: pythonmatplotlib

解决方案


这是画廊示例的改编,使用plt.waitforbuttonpress()

阻止调用与图形交互。等待用户输入,如果按下键则返回 True,如果按下鼠标按钮则返回 False,如果在超时秒内没有输入则返回 None。负值禁用超时。

只要你按下一个键,图形就会更新,如果你用鼠标点击循环就会中断。

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(5, 2)

for i in range(10):
    x = np.random.random((5, 2, 100))

    for r, xx in enumerate(x):
        ax[r, 0].plot(xx[0], 'ro')
        ax[r, 1].plot(xx[1], 'bx')

    plt.show()
    fig.canvas.draw()
    if plt.waitforbuttonpress():  # True for key, False for mouse
        for axx in ax.flat:
            axx.clear()
    else:
        break

另一种可能性是使用key_press_event. 为此,您需要将绘图更新组合在一个单独的函数中并相应地调用它。在本例中,我使用leftright键来切换数据。


import numpy as np
import matplotlib.pyplot as plt

n = 10
x = np.random.random((n, 5, 2, 100))
global i
i = 0

fig, ax = plt.subplots(5, 2)

def update(j):
    for axx in ax.flat:
        axx.clear()

    for r, xx in enumerate(x[j]):
        ax[r, 0].plot(xx[0], 'ro')
        ax[r, 1].plot(xx[1], 'bx')

def press_event(event):
    global i
    if event.key == 'left':
        i -= 1
    elif event.key == 'right':
        i += 1
    else:
        return
    i %= n
    update(i)

fig.canvas.mpl_connect('key_press_event', press_event)
update(0)

推荐阅读