【问题标题】:How to solve this plotting problem in serial communication?如何解决串行通信中的绘图问题?
【发布时间】:2019-06-07 00:12:42
【问题描述】:

这里是这个简单的代码:

#import serial
from tkinter import *
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial

fig = plt.gcf()
fig.show()
fig.canvas.draw()



ser = serial.Serial('COM35', 115200, timeout=.1)
while True:
  data = ser.readline()
  print(data)
  plt.plot(data)
  fig.canvas.draw()

现在当我运行它时,我得到了类似这样的东西..in pic
和数据值是这样的

但我需要这样的输出(这是连续图)..

但是在将 list 关键字添加到list(ser.readline()) 后,我收到此错误..

【问题讨论】:

  • @PatrickArtner 当我尝试绘制数据时,问题就来了。如果你看图表它不是连续的......每次它尝试在同一个图表中绘制数据(但我需要连续情节..(现场情节,带动画))..你明白我在说什么吗?
  • @PatrickArtner 检查上面的预期输出..谢谢
  • 感谢编辑 - 现在看起来更清晰了 :)
  • @PatrickArtner 不,数据在持续监控(它是实时数据,没有延迟)
  • 是的,我重新打开。但老实说,我不知道实际问题是什么。一方面有一个数字产生另一方面有一个错误。 @PatrickArtner 如果您觉得它比现有的更好,可以考虑在linked question 上给出您的答案。

标签: python python-3.x python-2.7 matplotlib serial-port


【解决方案1】:

这个答案不如使用 animation-api 优雅 - 但它有效。

你必须适应很多 - 为了给 Minimal, Complete, and Verifiable example 我必须实现我自己的“串行”数据提供者:

from itertools import cycle 
data = [0,0,0,0,0,0,0,0,0,2,25,64,92,119,132,139,124,123,103,71,38,3]
cyc = cycle(data)

def serial():
    from random import randint
    def create_data():
        for k in range(randint(2,3)): 
            yield next(cyc) 
    return list(create_data())

一种解决方法:

您还需要获取绘图的轴以调整显示的“区域”,然后您需要提供正确的 x 值作为“时间”和从串行读取的 y 值(您可以在时间的每次抽奖中增加一个“收到多少数据”变量):

from tkinter import *
from matplotlib import pyplot as plt 


fig, ax = plt.subplots() 
ax.set_ylim(-200, 200)
ax.set_xlim(0,110)
fig.show()
fig.canvas.draw() 

time = 0
last = 0
while True:
    # "animate" x-axis
    if time > 100:
        ax.set_xlim(time-100,time+10)
    data = serial()
    print(data)
    # add the last datapoint again so you get a continuous curve
    plt.plot([time-1]+[time+x for x in range(len(data))], [last]+data)
    # increment time
    time += len(data)
    # remember last data-value
    last = data[-1]
    fig.canvas.draw()

获取(省略文本输出 - 它只是重复上面不同分块的数据):

您可以通过彩色线段查看哪些数据被添加在一起。

【讨论】:

  • 你知道为什么图表不是正确的直流信号吗?有办法解决吗?
  • @user3764118 我不知道你所说的“正确的直流信号”是什么意思......它显示了它获得的数据。我选择使用您的问题提供的几个数据点并将它们循环,因此它是相同的波形......只是对数据进行了不同的分块。您可以使用轴限制和/或加宽/缩短 x 增量以使其更平坦/更锐利。如果你想要“矩形”波,你需要支持这一点的数据。
【解决方案2】:

您也可以更改为使用 matplotlib 的 animation 模块 - 这个答案深受 tacaswell answerHow to update values from serial port in matplotlib animations? 的启发

相同的数据生成器:

from itertools import cycle 
data = [0,0,0,0,0,0,0,0,0,2,25,64,92,119,132,139,124,123,103,71,38,3]
cyc = cycle(data)

def serial():
    from random import randint
    def create_data():
        for k in range(randint(2,3)): 
            yield next(cyc) 
    return list(create_data())

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

fig = plt.figure()
ax = plt.axes(xlim=(0, 150), ylim=(-200, 200)) 
max_points = 150
# fill initial artist with nans (so nothing draws)
line, = ax.plot(np.arange(max_points), 
                np.ones(max_points, dtype=np.float)*np.nan, 
                lw=2)
def init():
    return line,

def animate(i):
    y = serial() # arduino.readline()
    old_y = line.get_ydata()               # adjusted here for this question data, coming
    new_y = np.r_[old_y[len(y):], y]       # in as chunks rather then single values
    line.set_ydata(new_y)
    return line,


anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=False) 
plt.show()

对@tacaswell 的代码进行的调整是因为这个问题的数据需要对输出图进行其他限制,并且这个问题的数据提供了多个分块数据点,而不是单个数据点价值观。 def animate(i) 中的“数据刷新”必须适用于此。

【讨论】:

  • @tacaswell 我非常依赖您在stackoverflow.com/questions/20572815/… 中的回答 - 如果您觉得它太多(或归因不足),请随时告诉我,我会修复它(或删除它)
  • 第二个解决方案看起来不错,但为什么我在图表上得到一些 tump,当我打印data(串行数据)的值时,我得到很多'nan' 值,为什么?你有什么想法吗?
  • @user3764118 NaN 未绘制 - 数据图被初始化为 NaN - 然后由 animate() 函数增量填充 - 此代码不使用您的实际数据 - 此处的代码获取 [0,0,0,0,0,0,0,0,0,2,25,64,92,119,132,139,124,123,103,71,38,3]一直 - 这是您在问题中给出的值 - 它只是显示给定的数据 - 如果您的源数据没有导致您想要的结果,您可能必须更改某些内容以收集数据(或对其进行预处理)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
相关资源
最近更新 更多