0

I am doing a FIFO queue with temperature and dT lists and I am trying to plot the data. I have checked and the length of x,y,y1 are all 10 after they reach that many index values, so I know the if len(x)>10: part is working. However, when I plot, the real time plot does not update as I would expect. It essentially shows all 60 iterations as opposed to stopping at iteration 10 and just replacing the oldest point with the newest point. Is it an issue with the plotting or something else is the code? Note: Do not pay attention to anything before the empty list calls because that is just labjack code to get the equipment to read temperature.

from time import sleep
from labjack import ljm
import pylab as pl
import matplotlib.pyplot as plt

# Open T7 over USB
handle = ljm.openS("T7", "USB", "ANY")

# Configure thermocouple line on AIN0
ljm.eWriteName(handle, "AIN0_EF_INDEX", 22)  # Feature index for type K thermocouple
ljm.eWriteName(handle, "AIN0_EF_CONFIG_A", 1)  # Units. Default = Kelvin. 1 = Celsius. 2 = Fahrenheit.
ljm.eWriteName(handle, "AIN0_EF_CONFIG_B", 60052)  # CJC source, address for device temperature sensor
ljm.eWriteName(handle, "AIN0_EF_CONFIG_D", 1.0)  # Slope for CJC reading
ljm.eWriteName(handle, "AIN0_EF_CONFIG_E", 0.0)  # Offset for CJC reading

temperature = []
x = list()
y = list()
y1 = list()
li = list()
dT_tol = .5

plt.ion()
fig=plt.figure()

# Read loop
for i in range(60):
    # Get the thermocouple reading on AIN0. 
    tempC = ljm.eReadName(handle, "AIN0_EF_READ_A")
    temperature.append(tempC)
    dT = temperature[i]-temperature[i-1]

    x.append(i)
    y.append(temperature[i])
    y1.append(dT)

    if len(x)>10:
        del x[0]
        del y[0]
        del y1[0]


    if -dT_tol<dT<dT_tol:
        print "Temperature:","%.3f"% temperature[i],"         " "dT:", "%.3f"% dT, "         " "Steady State"
        sleep(1)
    else:
        print "Temperature:","%.3f"% temperature[i],"         " "dT:", "%.3f"% dT
        sleep(1)

    #print(len(x),len(y),len(y1))
    #sleep(1)

    #Plotting
    plt.figure(1)   
    plt.subplot(211)
    plt.axis([0,60,0,80])

    plt.scatter(x,y)
    plt.ylabel('Temperature (C)')

    plt.subplot(212)
    plt.axis([0,60,-4,4])
    plt.scatter(x,y1,zorder = 2)

    #Set dT steady state boundaries
    plt.axhspan(-dT_tol, dT_tol, color='#87CEFA', alpha=1, zorder = 1)

    plt.ylabel('dT')
    plt.xlabel('Time (s)')
    plt.show()
    plt.pause(.0001)

# Close handle
ljm.close(handle)
Zach Thomas
  • 147
  • 12

1 Answers1

1

When you want to dynamically update a plot, it is not recommended to 1) do the complete plot configuration in each iteration and 2) draw the plots on top of each other, e.g. plt.scatter(..) multiple times for the same position.

This question should provide a good basis for you to continue. In essence, you have to separate plot creation & configuration and setting the data & drawing.

Here is a very small (not very clean) working example you can begin with:

from time import sleep
import matplotlib.pyplot as plt

temperature = []
x = list()
y = list()
y1 = list()
li = list()
dT_tol = .5

plt.ion()
fig = plt.figure(1)
plt.subplot(211)

temp_plot = plt.scatter([],[])
plt.axis([0,60,0,80])
plt.ylabel('Temperature (C)')

plt.subplot(212)
delta_temp_plot = plt.scatter([],[],zorder = 2)
plt.axis([0,60,-4,4])
plt.axhspan(-dT_tol, dT_tol, color='#87CEFA', alpha=1, zorder = 1)
plt.ylabel('dT')
plt.xlabel('Time (s)')

plt.show()

# Read loop
for i in range(60):
    tempC = i * 3
    temperature.append(tempC)
    dT = temperature[i]-temperature[i-1]

    x.append(i)
    y.append(temperature[i])
    y1.append(dT)

    if len(x)>10:
        del x[0]
        del y[0]
        del y1[0]

    if -dT_tol<dT<dT_tol:
        print "Temperature:","%.3f"% temperature[i],"         " "dT:", "%.3f"% dT, "         " "Steady State"
        sleep(0.3)
    else:
        print "Temperature:","%.3f"% temperature[i],"         " "dT:", "%.3f"% dT
        sleep(0.3)

    temp_plot.set_offsets(zip(x, y))
    delta_temp_plot.set_offsets(zip(x,y1))

    fig.canvas.draw()
    fig.canvas.flush_events()

It all comes down to doing the configuration at the beginning and remembering the figure and its plots. Then, data is received, it is fed to the plots and subsequently the figure can be redrawn. Voilà, plotting works and this solution is also much faster.

(I think you also want to adapt the axes dynamically. Right now, you have a fixed x-axis of 0 to 60, but when you are only plotting the last ten measurements you have to rescale)

Community
  • 1
  • 1
Michael Hoff
  • 6,119
  • 1
  • 14
  • 38
  • that is excellent. and yes, I do need to find a new way to change my x-axis. I need to find a way to get it to start from 0-10 and then after 10 go from 1-11, 2-12 ... 50-60, as the iterations go through – Zach Thomas Jul 20 '16 at 01:45
  • Then also remember the axis objects (which are returned by `plt.subplot(..)`). They provide the functionality `set_xlim(..)`. See http://stackoverflow.com/questions/17895698/updating-the-x-axis-values-using-matplotlib-animation – Michael Hoff Jul 20 '16 at 09:16
  • thanks! I am still struggling trying to get set_xlim() to work with this code but hopefully it shall work soon enough – Zach Thomas Jul 20 '16 at 16:33