2

I am trying to plot real-time lectures from Arduino UNO's analogue input with matplotlib. My problem: The graph would not be shown. Only when I stop running the code (Ctrl+C), It will show the last values's graph.

when adding "print pData" line to the code in order to check whether the values are properly arriving to the computer, these are correctly displayed (shows the 25 values array each second) on the python terminal.

#!/usr/bin/python

from matplotlib import pyplot
import pyfirmata
from time import sleep

# Associate port and board with pyFirmata
port = '/dev/ttyACM0'
board = pyfirmata.Arduino(port)

# Using iterator thread to avoid buffer overflow
it = pyfirmata.util.Iterator(board)
it.start()

# Assign a role and variable to analog pin 0 
a0 = board.get_pin('a:0:i')

pyplot.ion()

pData = [0.0] * 25
fig = pyplot.figure()
pyplot.title('Real-time Potentiometer reading')
ax1 = pyplot.axes()
l1, = pyplot.plot(pData)
pyplot.ylim([0, 1])

while True:
    try:
        sleep(1)
        pData.append(float(a0.read()))
        pyplot.ylim([0, 1])
        del pData[0]
        l1.set_xdata([i for i in xrange(25)])
        l1.set_ydata(pData)  # update the data
        #print pData
        pyplot.draw()  # update the plot
    except KeyboardInterrupt:
        board.exit()
        break
3
  • Possible duplicate of Interactive plotting with Python via command line Commented Dec 29, 2015 at 22:46
  • @tyleha You don't need show() if you're using draw() Commented Dec 29, 2015 at 22:47
  • @Jason @tyleha Jason is right. Using show() doesn't fix the problem. Commented Dec 30, 2015 at 0:26

1 Answer 1

0

Here is a mock-up that uses matplotlib.animation for real-time plotting.

from matplotlib import pyplot
import matplotlib.animation as animation
import random

# Generate sample data
class Pin:
    def read(self):
        return random.random()
a0 = Pin()

n = 25
pData = [None] * n

fig, ax = pyplot.subplots()
pyplot.title('Real-time Potentiometer reading')
l1, = ax.plot(pData)
# Display past sampling times as negative, with 0 meaning "now"
l1.set_xdata(range(-n + 1, 1))
ax.set(ylim=(0, 1), xlim=(-n + 1, 0))

def update(data):
    del pData[0]
    pData.append(float(a0.read()))
    l1.set_ydata(pData)  # update the data
    return l1,

ani = animation.FuncAnimation(fig, update, interval=1000, blit=True)

try:
    pyplot.show()
finally:
    pass
    #board.exit()
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot! This is working almost OK: the initial line remains in the display while the values from the arduino are properly displayed and updated in other different line. How could I correct this?
I also adapted the following code (github.com/eliben/code-for-blog/blob/master/2008/…) and it is working fine, although is not that simple and you need to install wxPython module. Has more functionalities, though.
That's an easy fix: set the initialization to pData = [None] * n.

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.