python xdata 和 ydata 的长度必须相同

python xdata and ydata must be the same length

我认为这是一个有趣的问题。我想从服务器读取数据,以便我可以使用 matplotlib 实时绘制数据。目前我正在测试通过使用 random 模拟读取的值,我发现我遇到了这个错误:

  File "/usr/lib/python2.7/dist-packages/matplotlib/lines.py", line 632, in recache
    raise RuntimeError('xdata and ydata must be the same length')
RuntimeError: xdata and ydata must be the same length 

我不明白的是,如果我使用互斥锁来保护数据不被同时读取和更新,xdataydata 的大小可能会不匹配.您可以看看下面的非常简单代码:

import matplotlib.pyplot as plt
import time
from threading import Thread, Lock
import random

data = []
mutex = Lock()

# This just simulates reading from a socket.
def data_listener():
    while True:
        with mutex:
            data.append(random.random())

if __name__ == '__main__':
    t = Thread(target=data_listener)
    t.daemon = True
    t.start()

    # initialize figure
    plt.figure()
    ln, = plt.plot([])
    plt.ion()
    plt.show()
    plt.axis([0, 100, 0, 1])
    while True:
        plt.pause(0.1)
        with mutex:
            ln.set_xdata(range(len(data)))
            ln.set_ydata(data)
        plt.draw()

如您所见,我保证在追加数据或添加数据以更新绘图时,您必须获取互斥量,这意味着 len(xdata)==len(ydata)。任何关于我所做假设的想法都会有所帮助。

您可以自己复制并运行代码。

首先要注意的是:如果您使用 plt.pause(),则不需要 plt.draw(),因为后者无论如何都会调用前者。

现在,如果我像下面这样修改脚本,"error" 就不会打印出来,所以看起来 运行 没问题。

import matplotlib.pyplot as plt
from threading import Thread, Lock
import random

data = []
mutex = Lock()

# This just simulates reading from a socket.
def data_listener():
    while True:
        with mutex:
            data.append(random.random())

if __name__ == '__main__':
    t = Thread(target=data_listener)
    t.daemon = True
    t.start()

    # initialize figure
    plt.figure()
    ln, = plt.plot([])
    plt.ion()
    plt.show()
    plt.axis([0, 100, 0, 1])
    while True:
        with mutex:
            try:
                ln.set_xdata(range(len(data)))
                ln.set_ydata(data)
                plt.gca().set_xlim(len(data)-60,len(data) )
                plt.pause(0.1)
            except:
                print ("error")