【问题标题】:How to draw animated legend for subplots?如何为子图绘制动画图例?
【发布时间】:2018-04-27 11:39:34
【问题描述】:

我想用 ArtistAnimation 绘制动画子图。不幸的是,我无法弄清楚如何制作动画传奇。我尝试了在 StackOverflow 上找到的不同方法。如果我设法得到一个图例,它不是动画的,而只是所有动画步骤的图例。

我的代码如下所示:

import numpy as np
import pylab as pl
import matplotlib.animation as anim

fig, (ax1, ax2, ax3) = pl.subplots(1,3,figsize=(11,4))
ims   = []
im1   = ['im11','im12','im13']
im2   = ['im21','im22','im23']
x = np.arange(0,2*np.pi,0.1)

n=50
for i in range(n):
    for sp in (1,2,3):
        pl.subplot(1,3,sp)

        y1 = np.sin(sp*x + i*np.pi/n)
        y2 = np.cos(sp*x + i*np.pi/n)

        im1[sp-1], = pl.plot(x,y1)
        im2[sp-1], = pl.plot(x,y2)

        pl.xlim([0,2*np.pi])
        pl.ylim([-1,1])

        lab = 'i='+str(i)+', sp='+str(sp)
        im1[sp-1].set_label([lab])
        pl.legend(loc=2, prop={'size': 6}).draw_frame(False)

    ims.append([ im1[0],im1[1],im1[2], im2[0],im2[1],im2[2] ])

ani = anim.ArtistAnimation(fig,ims,blit=True)
pl.show()

我认为这段代码等同于这里使用的方法How to add legend/label in python animation,但显然我遗漏了一些东西。

我也尝试按照Add a legend for an animation (of Artists) in matplotlib 中的建议设置标签,但我并不真正了解如何在我的情况下使用它。像这样

im2[sp-1].legend(handles='-', labels=[lab])

我收到了AttributeError: 'Line2D' object has no attribute 'legend'

[编辑]:我没有说清楚:我想在图中的两条线都有一个图例。

【问题讨论】:

    标签: python animation matplotlib legend subplot


    【解决方案1】:

    我不知道图例到底应该是什么样子,但我想你只是想让它显示当前帧中一行的当前值。因此,您最好更新线的数据,而不是绘制 150 个新图。

    import numpy as np
    import pylab as plt
    import matplotlib.animation as anim
    
    fig, axes = plt.subplots(1,3,figsize=(8,3))
    ims   = []
    im1   = [ax.plot([],[], label="label")[0] for ax in axes]
    im2   = [ax.plot([],[], label="label")[0] for ax in axes]
    x = np.arange(0,2*np.pi,0.1)
    
    legs = [ax.legend(loc=2, prop={'size': 6})  for ax in axes]
    
    for ax in axes:
        ax.set_xlim([0,2*np.pi])
        ax.set_ylim([-1,1])
    plt.tight_layout()
    n=50
    def update(i):
        for sp in range(3):
            y1 = np.sin((sp+1)*x + (i)*np.pi/n)
            y2 = np.cos((sp+1)*x + (i)*np.pi/n)
    
            im1[sp].set_data(x,y1)
            im2[sp].set_data(x,y2)
    
            lab = 'i='+str(i)+', sp='+str(sp+1)
            legs[sp].texts[0].set_text(lab)
            legs[sp].texts[1].set_text(lab)
    
        return im1 + im2 +legs 
    
    ani = anim.FuncAnimation(fig,update, frames=n,blit=True)
    plt.show()
    

    【讨论】:

    • 看来我的最小示例有点太小了。 :) 我想要两条线的图例。我可以添加legs2 并手动将其移动到合适的位置,但它不会自动与第二个(此处为橙色)数据相关联。到目前为止,我更喜欢循环版本(而不是使用 def),因为实际上,我正在处理 30000 is 的数据,并且必须跳过其中的大部分。有没有办法在update(i) 中包含continuebreak 之类的条件?
    • 使用frames=something 给出的i 调用update 函数与循环for i in something 相同。因此,我认为这没有任何问题。当然,你也可以从上面的代码中做一个 ArtistAnimation,只需将图例添加到艺术家列表中。我用两个图例条目更新了答案。
    • 我没有设法让它与 ArtistAnimation 一起工作,但使用带有综合列表的 frames=n 完成了这项工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多