brn2bfre
brn2bfre

Reputation: 35

Adjusting the range of x axis for a live plot (serial data stream) in matplotlib

I've been toying with this bit of code off of the matplotlib examples page. I'm trying to get the x axis to maintain a given window. For example, the canvas will plot from x = 0 to 30, 1 to 31, 2 to 32. Right now my x grows on. I havent been able to define a set window size. Can anyone point me in the right direction.

From my trials, it seems whatever value x has, y needs to be of the same length. Well for my program, I just want to have a serial stream of data being plotted. Am I way off going this route?

import time
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)

y = []

def animate():

    while(1):
        data = random.random()
        y.append(data)
        x = range(len(y))

        line, = ax.plot(y)
        line.set_ydata(y)
        fig.canvas.draw()

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()

Upvotes: 2

Views: 5443

Answers (2)

weronika
weronika

Reputation: 2629

This is a simple version, which displays the last 30 points of y (actually it just discards all data except the last 30 points, since it sounds like you don't need to store it), but the x axis labels stay at 0-30 forever, which is presumably not what you want:

def animate(y, x_window):
    while(1):
        data = random.random()
        y.append(data)
        if len(y)>x_window:  
            y = y[-x_window:]
        x = range(len(y))
        ax.clear()
        line, = ax.plot(y)
        line.set_ydata(y)
        fig.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
y = []
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate(y,30))

So I add an offset variable to keep track of how much of y we've cut off, and just add that number to all the x axis labels with set_xticklabels:

def animate(y, x_window):
    offset = 0
    while(1):
        data = random.random()
        y.append(data)
        if len(y)>x_window:  
            offset += 1
            y = y[-x_window:]
        x = range(len(y))
        ax.clear()
        line, = ax.plot(y)
        line.set_ydata(y)
        ax.set_xticklabels(ax.get_xticks()+offset)
        fig.canvas.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
y = []
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate(y,30))

Does that work?

Upvotes: 0

matt
matt

Reputation: 4249

You can also change both the x and y data, then update the plot limits. I don't know how long you intend this to run, but you should probably consider dumping unneeded y-data at some point.

import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)

x = range(30)
y = [random.random() for i in x]
line, = ax.plot(x,y)

def animate(*args):
    n = len(y)
    for 1:
        data = random.random()
        y.append(data)

        n += 1
        line.set_data(range(n-30, n), y[-30:])
        ax.set_xlim(n-31, n-1)
        fig.canvas.draw()

fig.canvas.manager.window.after(100, animate)
plt.show()

Upvotes: 1

Related Questions