调整matplotlib中实时绘图的x轴范围(串行数据流)

2 投票
2 回答
5182 浏览
提问于 2025-04-16 19:47

我一直在玩一个来自matplotlib示例页面的代码。我想让x轴保持一个固定的范围。比如说,画布会从x = 0到30,接着是1到31,再到2到32。目前我的x轴是不断增长的。我还没能定义一个固定的窗口大小。有没有人能给我指个方向?

根据我的尝试,似乎x的值是什么,y的长度也需要和它一样。不过对于我的程序,我只是想绘制一串连续的数据流。我这样做是不是走错了方向?

import time
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)

y = []

def animate():

    while(1):
        data = random.random()
        y.append(data)
        x = range(len(y))

        line, = ax.plot(y)
        line.set_ydata(y)
        fig.canvas.draw()

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()

2 个回答

0

这是一个简单的版本,它只显示最后30个y值(实际上就是把除了最后30个点以外的数据都丢掉,因为看起来你不需要存储那些数据),但是x轴的标签一直保持在0到30,这显然不是你想要的效果:

def animate(y, x_window):
    while(1):
        data = random.random()
        y.append(data)
        if len(y)>x_window:  
            y = y[-x_window:]
        x = range(len(y))
        ax.clear()
        line, = ax.plot(y)
        line.set_ydata(y)
        fig.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
y = []
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate(y,30))

所以我添加了一个偏移量变量,用来记录我们切掉了多少y值,然后通过set_xticklabels把这个数字加到所有的x轴标签上:

def animate(y, x_window):
    offset = 0
    while(1):
        data = random.random()
        y.append(data)
        if len(y)>x_window:  
            offset += 1
            y = y[-x_window:]
        x = range(len(y))
        ax.clear()
        line, = ax.plot(y)
        line.set_ydata(y)
        ax.set_xticklabels(ax.get_xticks()+offset)
        fig.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
y = []
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate(y,30))

这样做有效吗?

1

你也可以同时改变x和y的数据,然后更新图表的范围。我不知道你打算让这个运行多久,但你可能应该考虑在某个时候清理掉不需要的y数据。

import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)

x = range(30)
y = [random.random() for i in x]
line, = ax.plot(x,y)

def animate(*args):
    n = len(y)
    for 1:
        data = random.random()
        y.append(data)

        n += 1
        line.set_data(range(n-30, n), y[-30:])
        ax.set_xlim(n-31, n-1)
        fig.canvas.draw()

fig.canvas.manager.window.after(100, animate)
plt.show()

撰写回答