【问题标题】:Looping over subplots in animation循环动画中的子图
【发布时间】:2020-06-29 17:46:39
【问题描述】:

我正在尝试在 matplotlib 子图中同时绘制四个动画。这是数据:

x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000)+7
x4 = np.random.uniform(14,20, 10000)
xs=[x1,x2,x3,x4]
bins=[np.linspace(-6,1, num=21),np.linspace(0,15, num=21),np.linspace(7,20, num=21),np.linspace(14,20, num=21)]

现在,我尝试了几种方法。这个效果很好:

def update1(curr):
    if curr==10000:
        ani.event_source.stop()
    for ax in axs:
        ax.cla()
    axs[0].hist(xs[0][:curr], bins=bins[0], normed=True)
    axs[1].hist(xs[1][:curr], bins=bins[1], normed=True)
    axs[2].hist(xs[2][:curr], bins=bins[2], normed=True)
    axs[3].hist(xs[3][:curr], bins=bins[3], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update1,interval=50)

但奇怪的是,这个没有:

def update2(curr):
    if curr==10000:
        ani.event_source.stop()
    for i in range(len(axs)):
        axs[i].cla()
    for i in range(len(axs)):
        x=xs[i]
        axs[i].hist(x[:curr], bins=bins[i], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update2,interval=50)

这只是绘制图形和轴,但不填充直方图。我知道它在动画之外有效(我试过)。有人可以解释发生了什么吗?我看过这些:

Plotting multiple subplot animations

Animation of histograms in subplot

第一个似乎是无用的,而第二个有效,但我的初始查询尚未解决。

【问题讨论】:

  • 我无法重现您的问题。这两种方法都对我有用(但我必须删除显然是undefined on 'Rectange' objectnormed=True 并且我看到了动画直方图。你使用的是什么python 版本?你能提供pip freeze 的输出吗?
  • 虽然问题已经解决,但为了完整起见,我将把它留在这里。 python==3.6.2matplotlib==1.19.0numpy==1.13.1。是的,我知道它们已经过时了,但在这件事上我真的别无选择。至于关于normed 的错误,现在已弃用,改用density。感谢您的帮助。

标签: python matplotlib matplotlib-animation


【解决方案1】:

将 python 3.8-devmatplotlib==3.2.2numpy==1.19.0 一起使用,您的代码对我来说运行良好。这是对我来说很好的整个脚本:

from matplotlib import numpy as np
from matplotlib import animation
from matplotlib import pyplot as plt

x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000)+7
x4 = np.random.uniform(14,20, 10000)
xs=[x1,x2,x3,x4]
bins=[
    np.linspace(-6,1, num=21),
    np.linspace(0,15, num=21),
    np.linspace(7,20, num=21),
    np.linspace(14, 20, num=21)
]


def update1(curr):
    if curr==10000:
        ani.event_source.stop()
    for ax in axs:
        ax.cla()
    axs[0].hist(xs[0][:curr], bins=bins[0], normed=True)
    axs[1].hist(xs[1][:curr], bins=bins[1], normed=True)
    axs[2].hist(xs[2][:curr], bins=bins[2], normed=True)
    axs[3].hist(xs[3][:curr], bins=bins[3], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani = animation.FuncAnimation(fig, update1, interval=50)
plt.show()


def update2(curr):
    if curr==10000:
        ani.event_source.stop()
    for i in range(len(axs)):
        axs[i].cla()
    for i in range(len(axs)):
        x=xs[i]
        axs[i].hist(x[:curr], bins=bins[i], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update2,interval=50)
plt.show()

唯一真正的区别是我必须取出导致错误的normed=True 部分:

AttributeError: 'Rectangle' object has no property 'normed'

我知道这不是答案,但我无法重现 OP 问题,所以我发布了一些有效的东西。

【讨论】:

  • 这段代码实际上是为 Coursera Jupyter Notebook 编写的,显然它运行了过时的 API matplotlib==1.19.0numpy==1.13.1。我通常尽量不更新内核,因为虽然代码在手动运行时可以工作,但(再次)过时的自动评分器会抛出错误。但是,我尝试更新它们,瞧,它现在完美运行。至于关于normed 的错误,现在已弃用,改用density。是的,这就是那个包的过时程度。
  • 感谢您抽出宝贵时间试用并提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2022-06-19
  • 2019-07-30
  • 2014-07-10
  • 1970-01-01
相关资源
最近更新 更多