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

时间:2018-07-16 00:52:08

标签: matplotlib arduino pyserial colormap

我正在尝试创建一个动画情节,该情节将使用来自串行端口的数据进行实时更新。数据由Arduino以8x8阵列流式传输。数据是来自红外摄像机的温度。我能够创建图形的实例,但无法获取文本以使用串行流数据进行更新。

我试图设置'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

1 个答案:

答案 0 :(得分:0)

可以使用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))对其进行了测试,因此我可能忽略了一些细节。让我知道它是如何工作的。