Home > Mobile >  Layer image and real time updating heatmap
Layer image and real time updating heatmap

Time:06-23

I have:

  • An image of an insole with 16 pressure sensors.
  • A 2*8 numpy array of pressure values for each sensor
  • Pressure values update in real time every 0.1[s]

Example image

I want to:

  • Display the image in the background of plot
  • Overlay to each pressure sensor(black dot) the Heatmap value of pressure applied
  • update pressure values every 0.1[s]

The code below does overlay the updating heatmap with background image, however I don't know how to reposition the heatmap to overlay with the sensors (black dots)


import matplotlib.pyplot as plt
import numpy as np
import time
 #Trial combining heatmap   backgoround image
fig = plt.figure()
ax = fig.add_subplot(111)
im = ax.imshow(np.random.random((300,400))) # Usually 2*8 but cannot see it 
img = plt.imread(r"..\Desktop\Example_image.PNG")

ax.imshow(img, alpha=0.5)
plt.show(block=False)

# draw some data in loop
for i in range(100):
    # wait for a second
    time.sleep(0.1)
    # PRESSURE SENSOR VALUES USUALLY 2*8, USING 300*400 SO THEY ARE VISIBLE
    Pressue_values = np.random.random((300,400))
    im.set_array(Pressue_values)
    # redraw the figure
    fig.canvas.draw()
    fig.canvas.flush_events()
    
    

How to map the 2*8 pressure values to the correct pressure sensor pixel?

Current result example - pixels are too small, need to map to correct position and expand to adjacent not correct overlay position

CodePudding user response:

This code uses a scatter plot to draw circles over the pressure sensors and update the colors based on the input data. You should update SENSOR_MIN and SENSOR_MAX to match your sensors (this prevents the color scale from changing when the inputs change).

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

# min and max values that the sensors will produce
SENSOR_MIN = 0
SENSOR_MAX = 1

def make_plot(background, coordinates, pressure_data):
    fig, ax = plt.subplots(1, 1)
    ax.imshow(background)

    coordinates = np.asarray(coordinates).reshape(-1, 2).T
    sc = ax.scatter(
        *coordinates,
        s=10.0**2,
        c=pressure_data.reshape(-1),
        cmap="viridis",
        vmin=SENSOR_MIN,
        vmax=SENSOR_MAX,
    )
    fig.colorbar(sc, label="pressure (some units)")
    return fig, sc

def update_plot(fig, sc, pressure_data):
    """Update the plot with new data and redraw the figure."""
    sc.set_array(pressure_data.reshape(-1))
    fig.canvas.draw()
    fig.canvas.flush_events()

def get_data():
    return np.random.random((2, 8))

if __name__ == "__main__":
    background_img = plt.imread("Example_image.PNG")
    # pixel coordinates of each sensor in the background image
    coords = [[[462, 106],
               [547, 113],
               [430, 156],
               [601, 237],
               [543, 222],
               [497, 221],
               [430, 216],
               [444, 266]],
              [[489, 439],
               [609, 463],
               [613, 564],
               [500, 574],
               [568, 641],
               [524, 643],
               [577, 688],
               [527, 683]]]

    fig, sc = make_plot(background_img, coords, get_data())
    # exit the script when the figure is closed
    fig.canvas.mpl_connect("close_event", lambda event: sys.exit())
    plt.show(block=False)

    # draw some data in loop
    while True:
        frame_start = time.perf_counter()
        pressure_values = get_data()
        # update the figure
        update_plot(fig, sc, pressure_values)
        # wait for 0.1s (including the time it took to update the plot)
        frame_time = time.perf_counter() - frame_start
        if frame_time < 0.1:
            plt.pause(0.1 - frame_time)
  • Related