Besides plotting data from files, we can use matplotlib to plot sensor data as it is sampled. To achieve this, we can use the plot-animation feature, which automatically calls a function to collect new data and update our plot.
Create the following script, called live_graph.py:
#!/usr/bin/python3 #live_graph.py import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import data_local as dataDevice PADDING=5 myData = dataDevice.device() dispdata = [] timeplot=0 fig, ax = plt.subplots() line, = ax.plot(dispdata) def update(data): global dispdata,timeplot timeplot+=1 dispdata.append(data) ax.set_xlim(0, timeplot) ymin = min(dispdata)-PADDING ymax = max(dispdata)+PADDING ax.set_ylim(ymin, ymax) line.set_data(range(timeplot),dispdata) return line def data_gen(): while True: yield myData.getNew()[1]/1000 ani = animation.FuncAnimation(fig, update, data_gen, interval=1000) plt.show() #End
We start by defining our dataDevice object and creating an empty array, dispdata[], which will hold all the data which has been collected. Next, we define our subplot and the line we are going to plot.
The FuncAnimation() function allows us to update a figure (fig) by defining an update function and a generator function. The generator function (data_gen()) will be called every interval (1,000 ms) and will produce a data value.
This example uses the core temperature reading that, when divided by 1,000, gives the actual temperature in degC:
yield myData.getNew()[1]/1000
The data value is passed to the update() function, which allows us to add it to our dispdata[] array that will contain all the data values to be displayed in the plot. We adjust the x axis range to be near the min and max values of the data. We also adjust the y axis to grow as we continue to sample more data.
Finally, we update the x and y axes data with our dispdata[] array (using the set_data() function), which will plot our samples against the number of seconds we are sampling. To use other data, or to plot data from the ADC, adjust the import for dataDevice and select the required channel (and scaling) in the data_gen() function.