0

I want to visualise values from a pressure sensing mat (32x32 pressure point) in realtime as a heatmap with MatPlotLib animation.

The mat outputs 1025 bytes (1024 values + 'end byte' which is always 255). I print these out from inside the animate function but it only works if I comment out plt.imshow(np_ints).

With plt.imshow the MatPlotLib window pops up and even reads the values... I see it in the heatmap when I start the program while pressing down on the sensor but when I release it, it seems like it slowly goes through all the readings in the serial buffer, instead of being realtime. Not sure if it's because I'm not handling the serial properly or something to do with how the FuncAnimation works. Can someone point me in the right direction please?

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

np.set_printoptions(threshold=1024,linewidth=1500)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

def animate(i):
    # np_ints = np.random.random((200, 200))              # FOR TESTING ONLY

    if ser.inWaiting:
        ser_bytes = bytearray(ser.read_until(b'\xFF'))  # should read 1025 bytes (1024 values + end byte)
        if len(ser_bytes) != 1025: return               # prevent error from an 'incomplete' serial reading

        ser_ints = [int(x) for x in ser_bytes]          
        np_ints = np.array(ser_ints[:-1])               # drop the end byte
        np_ints = np_ints.reshape(32, 32)

        print(len(ser_ints))
        print(np.matrix(np_ints))

        plt.imshow(np_ints)                             # THIS BRAKES IT

if __name__ == '__main__':

    ser = serial.Serial('/dev/tty.usbmodem14101', 11520)
    ser.flushInput()

    ani = animation.FuncAnimation(fig, animate, interval=10)
    plt.show()
  • Please provide a ![MIVE](https://stackoverflow.com/help/minimal-reproducible-example). Your code is overlaying with `plt.imshow`. Have a look at blitting. – cvanelteren Dec 22 '20 at 10:30

1 Answers1

1

The code below allows to animate random numbers using blitting. The trick is to not use plt.imshow but update the artist data. plt.imshow would create another image by getting the current axis. The slowdown would be caused by the many artists that are then in the figure.


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

np.set_printoptions(threshold=1024,linewidth=1500)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
# create dummy data
h  = ax.imshow(np.random.rand(32, 32))
def animate(i):
    # np_ints = np.random.random((200, 200))              # FOR TESTING ONLY

    # put here code for reading data
    np_ints = np.random.rand(32, 32) # not ints here, but principle stays the same

    # start blitting
    h.set_data(np_ints)
    return h

if __name__ == '__main__':


    ani = animation.FuncAnimation(fig, animate, interval=10)
    plt.show()
cvanelteren
  • 1,633
  • 9
  • 16