0

I am trying to display data from a sensor on a Matplotlib live chart.

I want to create a thread which reads the sensor continuously. I then use matplotlib.animation to update the graphs with whatever data is in the sensor reading list at that time.

The problem is that the matplotlib.animation only seems to read data from the sensor once, then freezes. Any idea on how to fix this ?

import random
import threading
import matplotlib.animation as animation
import matplotlib.pyplot as plt

def ReadSensors():  
    global listXData
    global listTemp
    # Should be sensor data. Using dummy random data for now...
    listTemp = [ random.randint(0,5) for x in listXData ] 


def UpdateFigure(oFrame):
    global listXData
    oCurve_Temp.set_data(listXData, listTemp)
    return oCurve_Temp, 

# Initialize data lists
listXData = range(0,100)
listTemp = [0 for x in listXData]

# Initialize graph
fig, ax = plt.subplots()
ax.set_title('Temperature')
ax.set_xlabel('Data Point')
ax.set_ylabel('[oC]')
ax.set_xlim( 0, 100)
ax.set_ylim( 0, 5)
oCurve_Temp, = ax.plot([],[])

# Starts reading sensor
oThread_ReadSensors = threading.Thread(target = ReadSensors)
oThread_ReadSensors.daemon = True
oThread_ReadSensors.start()

# Update graph
ani = animation.FuncAnimation(fig, UpdateFigure, interval=500)

plt.show()
1

1 Answer 1

1

You don't see any animation because the data does not actually change. So the animation shows all the same data all over again. It would make sense to actually change the data. Below the data is changed every 600 milliseconds, and the animation shows a new frame every 400 milliseconds, hence some frames show the same data as the previous one.

import time
import random
import threading
import matplotlib.animation as animation
import matplotlib.pyplot as plt

def ReadSensors():  
    global listXData
    global listTemp
    # Should be sensor data. Using dummy random data for now...
    while True: 
        listTemp = [ random.randint(0,5) for x in listXData ]
        time.sleep(0.6)

def UpdateFigure(oFrame):
    print "update"
    global listXData
    oCurve_Temp.set_data(listXData, listTemp)
    return oCurve_Temp, 

# Initialize data lists
listXData = range(0,100)
listTemp = [0 for x in listXData]

# Initialize graph
fig, ax = plt.subplots()
ax.set_title('Temperature')
ax.set_xlabel('Data Point')
ax.set_ylabel('[oC]')
ax.set_xlim( 0, 100)
ax.set_ylim( 0, 5)
oCurve_Temp, = ax.plot([],[])

# Starts reading sensor
oThread_ReadSensors = threading.Thread(target = ReadSensors)
oThread_ReadSensors.daemon = True
oThread_ReadSensors.start()

# Update graph
ani = animation.FuncAnimation(fig, UpdateFigure, interval=400)

plt.show()
# Join the thread not to run into 
# an unterminated threat when closing the figure
oThread_ReadSensors.join()
Sign up to request clarification or add additional context in comments.

1 Comment

Correct. The key was to include the random.randint line in a while(True) statement, as you mentionned. Thanks for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.