在 matplotlib 中使用 for 循环定义要动画的多个图 [英] Defining multiple plots to be animated with a for loop in matplotlib

查看:33
本文介绍了在 matplotlib 中使用 for 循环定义要动画的多个图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢 Jake Vanderplas,我知道如何使用 matplotlib 开始编写动画图.这是一个示例代码:

Thanks to Jake Vanderplas, I know how to start to code an animated plot with matplotlib. Here is a sample code:

from matplotlib import pyplot as plt
from matplotlib import animation

fig = plt.figure()

ax = plt.axes(xlim=(0, 2), ylim=(0, 100))

line, = plt.plot([], [])

def init():
    line.set_data([], [])
    return line,

def animate(i):
    line.set_data([0, 2], [0,i])
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

plt.show()

假设现在我想绘制大量的函数(这里说四个),在循环的帮助下定义.我做了一些伏都教编程,试图理解如何模仿下面的逗号,这就是我得到的(不用说它不起作用:AttributeError: 'tuple' object has no attribute 'axes').

Suppose now I'd like to plot tons of functions (say four here), defined with the help of a loop. I did some voodoo programming, trying to understand how to mimic the comma following line and here is what I got (needless to say that it does not work: AttributeError: 'tuple' object has no attribute 'axes').

from matplotlib import pyplot as plt
from matplotlib import animation

fig = plt.figure()

ax = plt.axes(xlim=(0, 2), ylim=(0, 100))

line = []
N = 4

for j in range(N):
    temp, = plt.plot([], [])
    line.append(temp)

line = tuple(line)

def init():
    for j in range(N):
        line[j].set_data([], [])
    return line,

def animate(i):
    for j in range(N):
        line[j].set_data([0, 2], [10 * j,i])
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

plt.show()

我的一些问题是:我怎样才能让它发挥作用?奖金(可能链接):line, = plt.plot([], [])line = plt.plot([], []) 之间有什么区别?>?

Some my question is: how can I make it work? Bonus (probably linked): what is the difference between line, = plt.plot([], []) and line = plt.plot([], [])?

谢谢

推荐答案

在下面的解决方案中,我展示了一个更大的示例(还有 条形图),可以帮助人们更好地理解应该做什么其他情况.在代码之后我解释了一些细节并回答了奖金问题.

In the solution below I showcase a bigger example (with also bar plot) that may help people understand better what should be done for other cases. After the code I explain some details and answer the bonus question.

import matplotlib
matplotlib.use('Qt5Agg') #use Qt5 as backend, comment this line for default backend

from matplotlib import pyplot as plt
from matplotlib import animation

fig = plt.figure()

ax = plt.axes(xlim=(0, 2), ylim=(0, 100))

N = 4
lines = [plt.plot([], [])[0] for _ in range(N)] #lines to animate

rectangles = plt.bar([0.5,1,1.5],[50,40,90],width=0.1) #rectangles to animate

patches = lines + list(rectangles) #things to animate

def init():
    #init lines
    for line in lines:
        line.set_data([], [])

    #init rectangles
    for rectangle in rectangles:
        rectangle.set_height(0)

    return patches #return everything that must be updated

def animate(i):
    #animate lines
    for j,line in enumerate(lines):
        line.set_data([0, 2], [10 * j,i])

    #animate rectangles
    for j,rectangle in enumerate(rectangles):
        rectangle.set_height(i/(j+1))

    return patches #return everything that must be updated

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)

plt.show()

说明

我们的想法是绘制您需要的内容,然后重用艺术家(查看更多此处)由 matplotlib 返回.这是通过首先绘制您想要的虚拟草图并保留 matplotlib 给您的对象来完成的.然后在您的 initanimate 函数中,您可以更新需要动画的对象.

Explanation

The idea is to plot what you need and then reuse the artists (see more here) returned by matplotlib. This is done by first plotting a dummy sketch of what you want and keeping the objects matplotlib gives you. Then on your init and animate functions you can update the objects that need to be animated.

请注意,在 plt.plot([], [])[0] 中,我们得到了一个 line 艺术家,因此我用 [plt.plot([], [])[0] for _ in range(N)].另一方面,plt.bar([0.5,1,1.5],[50,40,90],width=0.1) 返回一个容器,可以为 矩形艺术家.list(rectangles) 只是将这个容器转换成一个列表,与lines 连接起来.

Note that in plt.plot([], [])[0] we get a single line artist, thus I collect them with [plt.plot([], [])[0] for _ in range(N)]. On the other hand plt.bar([0.5,1,1.5],[50,40,90],width=0.1) returns a container that can be iterated for the rectangle artists. list(rectangles) just convert this container into a list to be concatenated with lines.

我将线条与矩形分开,因为它们的更新方式不同(并且是不同的艺术家),但是 initanimate 返回所有这些.

I separate the lines from the rectangles because they are updated differently (and are different artists) but init and animate return all of them.

回答奖励问题:

  1. line, = plt.plot([], [])plt.plot 返回的列表的第一个元素分配给可验证的 line.
  2. line = plt.plot([], []) 只分配整个列表(只有一个元素).
  1. line, = plt.plot([], []) assign the first element of the list returned by plt.plot to the veriable line.
  2. line = plt.plot([], []) just assign the whole list (of only one element).

这篇关于在 matplotlib 中使用 for 循环定义要动画的多个图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆