Python Matplotlib:在循环

时间:2017-08-29 13:17:44

标签: python-3.x loops matplotlib

我想每x秒更新一次绘图并保持共享的x轴。问题是当使用cla()命令时,sharedx会丢失,当不使用cla()时,绘图不会更新,而是“过度绘制”,如下例所示:

import matplotlib.pyplot as plt
import pandas as pd

data = pd.DataFrame([[1,2,1],[3,1,3]], index = [1,2])

n_plots = data.shape[1]

fig, axs = plt.subplots(n_plots , 1, sharex = True)
axs = axs.ravel()

while True:
    for i in range(n_plots):
        #axs[i].cla()
        axs[i].plot(data.iloc[:,i])
        axs[i].grid()

    plt.tight_layout()
    plt.draw()

    plt.pause(5)

    data = pd.concat([data,data]).reset_index(drop = True)

通过取消注释axs [i] .cla()行可以看到行为。

所以问题是: 如何在while循环中更新绘图(没有预定义的子图数)(我想更新一些数据)并保持共享的x轴?

提前致谢

1 个答案:

答案 0 :(得分:0)

首先,要使用matplotlib生成动画,您应该查看Advanced Types。你会在这个主题上找到关于SO的大量帖子,例如:FuncAnimation

一般准则是不重复调用plt.plot(),而是使用set_data()返回的Line2D对象的plot()函数。换句话说,在代码的第一部分中,您实例化一个带有空图

的对象
l, = plt.plot([],[])

然后,每当您需要更新您的绘图时,您保留相同的对象(不要清除轴,不要进行新的plot()调用),只需更新其内容:

l.set_data(X,Y)
# alternatively, if only Y-data changes
l.set_ydata(Y)  # make sure that len(Y)==len(l.get_xdata())!

编辑:这是一个显示3轴共享x轴的最小示例,就像您要尝试的那样

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

N_points_to_display = 20
N_lines = 3
line_colors = ['r','g','b']

fig, axs = plt.subplots(N_lines, 1, sharex=True)
my_lines = []
for ax,c in zip(axs,line_colors):
    l, = ax.plot([], [], c, animated=True)
    my_lines.append(l)

def init():
    for ax in axs:
        ax.set_xlim((0,N_points_to_display))
        ax.set_ylim((-1.5,1.5))
    return my_lines

def update(frame):
    #generates a random number to simulate new incoming data
    new_data = np.random.random(size=(N_lines,))
    for l,datum in zip(my_lines,new_data):
        xdata, ydata = l.get_data()
        ydata = np.append(ydata, datum)
        #keep only the last N_points_to_display
        ydata = ydata[-N_points_to_display:]
        xdata = range(0,len(ydata))
        # update the data in the Line2D object
        l.set_data(xdata,ydata)
    return my_lines

anim = FuncAnimation(fig, update, interval=200,
                    init_func=init, blit=True)

Dynamically updating plot in matplotlib