martin_0004
martin_0004

Reputation: 397

matplotlib.animation cannot update using data from threading

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()

Upvotes: 0

Views: 720

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339775

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()

Upvotes: 1

Related Questions