user3764118
user3764118

Reputation: 65

How to solve this plotting problem in serial communication?

Here this simple code:

#import serial
from tkinter import *
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial

fig = plt.gcf()
fig.show()
fig.canvas.draw()



ser = serial.Serial('COM35', 115200, timeout=.1)
while True:
  data = ser.readline()
  print(data)
  plt.plot(data)
  fig.canvas.draw()

now when i run this i'm getting something like this..in picenter image description here
and the data values are like thisenter image description here

but i need output something like this (which is continuous graph)..enter image description here

but after adding the list key word on to the list(ser.readline()) I get this error..enter image description here

Upvotes: 1

Views: 434

Answers (2)

Patrick Artner
Patrick Artner

Reputation: 51683

You could also change to use the animation module of matplotlib - this answer is heavily inspired by tacaswell answer to How to update values from serial port in matplotlib animations?

Same data generator:

from itertools import cycle 
data = [0,0,0,0,0,0,0,0,0,2,25,64,92,119,132,139,124,123,103,71,38,3]
cyc = cycle(data)

def serial():
    from random import randint
    def create_data():
        for k in range(randint(2,3)): 
            yield next(cyc) 
    return list(create_data())

from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np

fig = plt.figure()
ax = plt.axes(xlim=(0, 150), ylim=(-200, 200)) 
max_points = 150
# fill initial artist with nans (so nothing draws)
line, = ax.plot(np.arange(max_points), 
                np.ones(max_points, dtype=np.float)*np.nan, 
                lw=2)
def init():
    return line,

def animate(i):
    y = serial() # arduino.readline()
    old_y = line.get_ydata()               # adjusted here for this question data, coming
    new_y = np.r_[old_y[len(y):], y]       # in as chunks rather then single values
    line.set_ydata(new_y)
    return line,


anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=False) 
plt.show()

The adaptations made to @tacaswell's code are due to the fact that this questions data needed other limits for the output graph and that the data coming in for this question provides multiple, chunked datapoints, not single values. The "data-refresh" in def animate(i) had to be adapted to work for this.

Upvotes: 0

Patrick Artner
Patrick Artner

Reputation: 51683

This answer is not as elegant as using the animation-api - but it works.

You have to adapt quite a lot - for sake of giving a Minimal, Complete, and Verifiable example I had to implement my own "serial" dataprovider:

from itertools import cycle 
data = [0,0,0,0,0,0,0,0,0,2,25,64,92,119,132,139,124,123,103,71,38,3]
cyc = cycle(data)

def serial():
    from random import randint
    def create_data():
        for k in range(randint(2,3)): 
            yield next(cyc) 
    return list(create_data())

One way to solve it:

You need to get the the axes of your plot as well to adjust the "area" that is shown, then you need to supply correct x-values as "time" and the y-values as reading from serial (you can increment a "how many data received" variable on each draw for the time):

from tkinter import *
from matplotlib import pyplot as plt 


fig, ax = plt.subplots() 
ax.set_ylim(-200, 200)
ax.set_xlim(0,110)
fig.show()
fig.canvas.draw() 

time = 0
last = 0
while True:
    # "animate" x-axis
    if time > 100:
        ax.set_xlim(time-100,time+10)
    data = serial()
    print(data)
    # add the last datapoint again so you get a continuous curve
    plt.plot([time-1]+[time+x for x in range(len(data))], [last]+data)
    # increment time
    time += len(data)
    # remember last data-value
    last = data[-1]
    fig.canvas.draw()

To get (text output omitted - it just repeats the data from above differently chunked):

animation

You can see by the colored line-segments which data was added together.

Upvotes: 1

Related Questions