简体   繁体   中英

python matplotlib multiple lines animation

I'm trying to create an animation with matplotlib to plot several datasets simultaneously in one animation. The problem is that two of my datasets have 50 points in them, and the third one has got 70000 points. Therefore, simultaneous plotting (with the same interval between the points) is useless, as the first two datasets are done plotting when the third one is only beginning to show.

Therefore, I'm trying to get the datasets to plot in separate animation calls (with different intervals, ie speed of plotting) but on a single plot. The problem with that is that the animation is shown only for the last dataset called.

Please see the code for random data below:

import numpy as np
from matplotlib.pyplot import *
import matplotlib.animation as animation
import random

dataA = np.random.uniform(0.0001, 0.20, 70000)
dataB = np.random.uniform(0.90, 1.0, 50)
dataC = np.random.uniform(0.10, 0.30, 50)

fig, ax1 = subplots(figsize=(7,5))

# setting the axes
x1 = np.arange(0, len(dataA), 1)
ax1.set_ylabel('Percentage %')
for tl in ax1.get_xticklabels():
    tl.set_color('b')

ax2 = ax1.twiny()
x2 = np.arange(0, len(dataC), 1)
for tl in ax2.get_xticklabels():
    tl.set_color('r')

ax3 = ax1.twiny()
x3 = np.arange(0, len(dataB), 1)
for tl in ax3.get_xticklabels():
    tl.set_color('g')

# set plots
line1, =ax1.plot(x1,dataA, 'b-', label="dataA")
line2, =ax2.plot(x2,dataC, 'r-',label="dataB")
line3, =ax3.plot(x3, dataB, 'g-', label="dataC")

# set legends
ax1.legend([line1, line2, line3], [line1.get_label(),line2.get_label(), line3.get_label()])

def update(num, x, y, line):
    line.set_data(x[:num], y[:num])
    line.axes.axis([0, len(y), 0, 1]) #[xmin, xmax, ymin, ymax]
    return line, 


ani = animation.FuncAnimation(fig, update, len(x1), fargs=[x3, dataB, line3],interval=150,  blit=True, repeat=False)

ani = animation.FuncAnimation(fig, update, len(x1), fargs=[x1, dataA, line1],interval=5,  blit=True, repeat=False)

ani = animation.FuncAnimation(fig, update, len(x1), fargs=[x2, dataC, line2],interval=150,  blit=True, repeat=False)

# if the first two 'ani' are commented out, it live plots the last one, while the other two are plotted static

show()

The plot in the end should look like this: http://i.imgur.com/RjgVYxr.png

But the point is to get the animation simultaneously (but at different paces) draw the lines.

Simpler than using separate animation calls is to update all of your lines in the same animation call, but at a different rate. In your case, only update the red and green lines every (70000/50)th call to update .

You can do this by changing your code starting at your update function to the following:

def update(num):
    ratio = 70000/50
    i = num/ratio
    line1.set_data(x1[:num], dataA[:num])
    if num % ratio == 0:
        line2.set_data(x2[:i], dataC[:i])
        line3.set_data(x3[:i], dataB[:i])


ani = animation.FuncAnimation(fig, update, interval=5, repeat=False)

show()

Note the if num % ratio == 0 statement, which only executes the following lines if num is divisible by ratio. Also, you need to create a separate counter for the lines that update more slowly. In this case, I've used i .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM