【问题标题】:How to update text in matplotlib with serial data from Arduino?如何使用来自 Arduino 的串行数据更新 matplotlib 中的文本?
【发布时间】:2018-07-16 00:52:07
【问题描述】:

我正在尝试创建一个动画图,该图使用来自我的串行端口的数据实时更新。数据由 8x8 阵列中的 Arduino 流入。数据是红外热像仪的温度。我能够创建一个图形的实例,但我无法使用串行流数据更新文本。

我尝试设置 'plt.show(block=False)' 以便脚本继续执行,但这会使该图完全为空,并将其缩放为一个带有加载光标的小窗口,该加载光标将继续加载。

我只希望文本使用数组数据以及新规范化数据中的颜色进行更新。

如何使用 matplotlib 中的串行数据更新文本?

谢谢!

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import serial
import time

tempdata = serial.Serial("COM3",9600)
tempdata.timeout = 100
strn = []

rows = ["A", "B", "C", "D",
              "E", "F", "G","H"]
columns = ["1", "2", "3", "4",
              "5", "6", "7","8"]

print("AMG8833 8x8 Infrared Camera")
time.sleep(0.75)
print("Connected to: " + tempdata.portstr)
time.sleep(0.75)
print("Initializing Camera...")

tempsArray = np.empty((8,8))

while True: #Makes a continuous loop to read values from Arduino

    fig, ax = plt.subplots() 
    im = ax.imshow(tempsArray,cmap='plasma')
    tempdata.flush()
    strn = tempdata.read_until(']') #reads the value from the serial port as a string
    tempsString = np.asarray(strn)
    tempsFloat = np.fromstring(tempsString, dtype=float, sep= ', ')

     # Axes ticks
    ax.set_xticks(np.arange(len(columns)))
    ax.set_yticks(np.arange(len(rows)))
    # Axes labels
    ax.set_xticklabels(columns)
    ax.set_yticklabels(rows)
    # Rotate the tick labels and set their alignment.
    plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
                     rotation_mode="anchor")

    tempsArray.flat=tempsFloat  
    im.set_array(tempsArray)

    ax.set_title("")
    fig.tight_layout()
    #Loop over data dimensions and create text annotations.
    for i in range(len(rows)):
        for j in range(len(columns)):
            text = ax.text(j, i, tempsArray[i, j],
                                ha="center", va="center", color="w")

    plt.show()

Heat Map

【问题讨论】:

    标签: matplotlib arduino pyserial colormap


    【解决方案1】:

    这种动态更新可以通过matplotlib的interactive mode来实现。您的问题的答案与this one 非常相似:基本上您需要使用ion() 启用交互模式,然后更新绘图无需调用show()(或相关)函数。 此外,情节和子情节只能在输入循环之前创建一次。

    这是修改后的例子:

    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    import serial
    import time
    
    tempdata = serial.Serial("COM3",9600)
    tempdata.timeout = 100
    strn = []
    
    rows = ["A", "B", "C", "D",
                  "E", "F", "G","H"]
    columns = ["1", "2", "3", "4",
                  "5", "6", "7","8"]
    
    print("AMG8833 8x8 Infrared Camera")
    time.sleep(0.75)
    print("Connected to: " + tempdata.portstr)
    time.sleep(0.75)
    print("Initializing Camera...")
    
    tempsArray = np.empty((8,8))
    
    plt.ion()
    
    fig, ax = plt.subplots()
    # The subplot colors do not change after the first time
    # if initialized with an empty matrix
    im = ax.imshow(np.random.rand(8,8),cmap='plasma')
    
    # Axes ticks
    ax.set_xticks(np.arange(len(columns)))
    ax.set_yticks(np.arange(len(rows)))
    # Axes labels
    ax.set_xticklabels(columns)
    ax.set_yticklabels(rows)
    # Rotate the tick labels and set their alignment.
    plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
                     rotation_mode="anchor")
    
    ax.set_title("")
    fig.tight_layout()
    
    text = []
    
    while True: #Makes a continuous loop to read values from Arduino
    
        tempdata.flush()
        strn = tempdata.read_until(']') #reads the value from the serial port as a string
        tempsString = np.asarray(strn)
        tempsFloat = np.fromstring(tempsString, dtype=float, sep= ', ')
    
        tempsArray.flat=tempsFloat  
        im.set_array(tempsArray)
    
        #Delete previous annotations
        for ann in text:
            ann.remove()
        text = []
    
        #Loop over data dimensions and create text annotations.
        for i in range(len(rows)):
            for j in range(len(columns)):
                text.append(ax.text(j, i, tempsArray[i, j],
                                    ha="center", va="center", color="w"))
    
        # allow some delay to render the image
        plt.pause(0.1)
    
    plt.ioff()
    

    注意:此代码对我有用,但由于我现在没有 Arduino,我使用随机生成的帧序列 (np.random.rand(8,8,10)) 对其进行了测试,所以我可能忽略了一些细节。让我知道它是如何工作的。

    【讨论】:

    • 我怎样才能让颜色相对于每一帧而不是自初始化以来的值历史进行标准化?
    • 相机喜欢在整个阵列的帧内随机抛出“-1”,这会破坏标准化。你会建议什么来解决这个问题并在正常温度范围(20-40 *C)内显示颜色。我试图设置 vmax 和 vmin 但这似乎并没有改变任何东西。
    • 不规范化 -1 值是否足够,也许将它们设置为 0?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多