【问题标题】:How to add legend/label in python animation如何在python动画中添加图例/标签
【发布时间】:2016-06-11 05:15:06
【问题描述】:

我想在 python 动画中添加一个图例,比如下面的line.set_label()。它类似于plt.plot(x,y,label='%d' %*variable*)

但是,我发现代码在这里不起作用。动画仅显示线条变化,但没有可用的标签或图例。我该如何解决这个问题?

 from matplotlib import pyplot as plt 
 from matplotlib import animation

fig = plt.figure()

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

N = 3
lines = [plt.plot([], [])[0] for _ in range(N)]


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

def animate(i):
    for j,line in enumerate(lines):
        line.set_data([0, 2], [10*j,i])
        line.set_label('line %d, stage %d'%(j,i))
    return lines

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

plt.show()

【问题讨论】:

标签: python matplotlib


【解决方案1】:

我根本不是 matplotlib 方面的专家,但在 Double Pendulum animation 中,它们显示的文本会发生变化,这会导致一些可以帮助您的变化。

要获得线条实际颜色的图例,您可以将初始设置 lines 更改为:

lines = [plt.plot([], [], label = 'line {}'.format(i))[0] for i in range(N)]

或在init() 函数的for 循环中添加line.set_label()。这两个似乎都按预期工作。至少如果您在plt.show() 之前添加plt.legend(loc="upper left")

但是set_labelanimate() 函数中不起作用,但是根据链接的动画,您可以使用添加到动画中的特定文本字段,这似乎工作得很好。在lines初始化后添加如下代码:

texts = [ax.text(0.80, 0.95-i*0.05,  '', transform=ax.transAxes) for i in range(N)]

并将animate() 更改为:

def animate(i):
    for j in range(N):
        lines[j].set_data([0, 2], [10*j,i]) #, label="hei {}".format(i))
        texts[j].set_text('line %d, stage %d'%(j,i))
    return lines

这会将文本放置在靠近右上角的位置,并针对每个动画步骤进行更新。由于线条仍然显示其图例,您可以简化为仅显示舞台的文本。但我将消息的微调留给您自行决定。

附录:延长 Line2D

另一种选择可能可能是扩展lines.Line2D 并在您的动画中使用这些行,类似于this article。不确定这是否适用于动画,但如果您无法使用上述方法,这可能值得一试。

【讨论】:

    【解决方案2】:

    您必须在动画函数中返回图例才能对其进行渲染。 试试这个吧:

    legend = plt.legend()
    def animate(i):
        for j,line in enumerate(lines):
            line.set_data([0, 2], [10*j,i])
            line.set_label('line %d, stage %d'%(j,i))
        legend.remove()
        legend = plt.legend()
        return lines + [legend]
    

    你还应该在你的init函数中包含相同的代码,在调整窗口大小时使用init,否则调整大小时图例会消失

    【讨论】:

    • 您是否缺少global legend
    【解决方案3】:

    您可以在下面尝试这个最小的工作示例。图例hlegend的句柄由文本htext的句柄组成,因此我们可以在hf_frame中更新htext的内容。

    import matplotlib
    import matplotlib.pyplot as plt
    import numpy as np
    
    fig, ax = plt.subplots()
    N0 = 20
    xdata = np.linspace(0, 2*np.pi, 100)
    omega = np.linspace(1, 4, N0)
    ydata = np.sin(omega[:,np.newaxis]*xdata)
    hline0, = ax.plot(xdata, ydata[0], label=f'omega={omega[0]:.3f}')
    hlegend = ax.legend(loc='upper right')
    def hf_frame(ind0):
        hline0.set_data(xdata, ydata[ind0])
        label_i = f'{omega[ind0]:.3f}'
        # hline0.set_label(label_i) #doesn't help
        htext = hlegend.get_texts()[0]
        htext.set_text(label_i)
        return hline0,htext
    ani = matplotlib.animation.FuncAnimation(fig, hf_frame, frames=N0, interval=200)
    plt.show()
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    • 这个例子对我不起作用。当我运行代码时,我得到UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.
    • 哎呀,我忘了在最后添加plt.show()
    猜你喜欢
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多