[Matplotlib-users] Animate CSV multiple lines

fredz0003 ic3balandran at yahoo.com
Thu Mar 21 01:50:18 EDT 2019


Hi,

I have been trying to accomplish this for a while that I finally decided to
reach out for some help. I have browse nearly 100 stackoverflow posts, and
others on the web, youtube. I've tried nearly a dozen scripts and I can't
seem to find a way to do this. I can animate a line just fine, but when it
comes to multiple lines I get stuck and don't know how to handle that in the
animate() function. I believe the emitData is where things go wrong, but I
don't understand how exactly that method needs to be written for returning
multiple lines.


Tasks:
1 > Import csv data with pandas
2 > Animate lines with matplotlib

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.lines import Line2D
import pandas as pd

import math
import time

# read csv data into pd dataframes
df = pd.read_csv("data_log.csv")

# Initalize script constants
ymin = -1.1
ymax = 1.1
    
linesPerPlot = 3

samplesPerFrame = 1
framesPerSecond = 20
secondsPerPlot = 5

# Calculate dependent constants
samplesPerSecond = samplesPerFrame * framesPerSecond
samplesPerPlot =  samplesPerSecond * secondsPerPlot
secondsPerSample = 1.0/samplesPerSecond
millisPerFrame = 1000.0/framesPerSecond

# Define core functions
def makeLine(ax, maxt, dt, ymin, ymax, color):
    """Make an empty Line2D for the initial chart."""
    nvalues = int(round(maxt/dt))

    tdata = [dt*tm for tm in range(nvalues)]
    ydata = [0 for tm in range(nvalues)]

    line = Line2D(tdata, ydata, color=color)
    ax.add_line(line)
    ax.set_ylim(ymin, ymax)
    
    return line

        
def makeChart(ax, maxt, dt, linesPerPlot, ymin, ymax):
    """Make a chart and return a list of the lines it contains."""
    colors = [ 'r', 'b', 'g', 'k' ]

    # Make the lines and store in a list.  
    lines = [] 
    for iline in range(0,linesPerPlot):
        lines.append(makeLine(ax, maxt, dt, ymin, ymax, colors[iline %
len(colors)]))
    
    ax.set_xlim(0, maxt)
    
    return lines


def initDisplay(lines):
    """Init display."""
    return lines


def updateLine(line, ys):
    """Update the data in one line, popping off the last value."""
    tdata, ydata = line.get_data()
    for y in ys:
        ydata.append(y)
        ydata.pop(0)
    line.set_data(tdata, ydata)
    
    return line


def updateLines(lines, arrays):
    """Update individual lines and return a sequence of artists to the
animator."""
    artists = []
    for iline in range(len(lines)):
        artists.append(updateLine(lines[iline], arrays[iline]))
        
    return artists


def emitData(linesPerPlot, samplesPerFrame):
    """Create the data that will be plotted."""
    nsample = 0
    while True:
        samples = [[] for i in range(linesPerPlot)]
        # I think the series pd needs to be here
        # in the foorloop only so many samples are extracted
        for _ in range(samplesPerFrame):
            nsample = nsample + 1
            for iline in range(linesPerPlot):
                pi_increment = (math.pi/(10.0 * (iline+1)))
                samples[iline].append(math.sin(nsample * pi_increment))
                #samples[iline].append(df[(df.columns[iline + 1])]) # +1
because first column is time
                #samples[iline].append(df.iloc[:,iline+1:].values)

        yield samples


# Make chart.
fig, ax = plt.subplots()
lines = makeChart(ax, secondsPerPlot, secondsPerSample, linesPerPlot, ymin,
ymax)

# Start the animator.
update = lambda samples: updateLines(lines, samples)
emitter = lambda: emitData(linesPerPlot, samplesPerFrame)
init = lambda: initDisplay(lines)

ani = animation.FuncAnimation(fig, update, emitter, init_func=init,
interval=millisPerFrame, blit=True)

plt.show()

Thanks for the help! Any document or article that can point me in the right
direction would be appreciated.



--
Sent from: http://matplotlib.1069221.n5.nabble.com/matplotlib-users-f3.html


More information about the Matplotlib-users mailing list