【问题标题】:Animation based on only updating colours in a plot仅基于更新绘图中的颜色的动画
【发布时间】:2013-12-01 23:13:44
【问题描述】:

我有一个包含大量线条的情节。在每一步,线条的颜色都应该在动画中更新,但是在线条上做一个 for 循环似乎真的很昂贵。有没有更好的方法来做到这一点?

这是我的代码:

import numpy as np
lines=[]
from matplotlib import pyplot as plt
import matplotlib.animation as animation

#initial plot
fig=plt.figure()
ax=plt.subplot(1,1,1)
for i in range(10):
    lines.append([])
    for j in range(10):
        lines[i].append(ax.plot([i,j],color='0.8'))
lines=np.asarray(lines)


##Updating the colors 10 times 
im=[]
for steps in range(10):
    colors=np.random.random(size=(10,10))
    for i in range(10):
        for j in range(10):
            lines[i,j][0].set_color(str(colors[i,j])) 
    plt.draw()
#    im.append(ax)
    plt.pause(.1)
#ani = animation.ArtistAnimation(fig, im, interval=1000, blit=True,repeat_delay=1000)
plt.show()

另外,我无法与动画艺术家合作!我用画法。动画线条有什么问题

现在将这 10 个增加到 100 个会使程序变得非常缓慢:

import numpy as np
lines=[]
from matplotlib import pyplot as plt
import matplotlib.animation as animation

#initial plot
fig=plt.figure()
ax=plt.subplot(1,1,1)
for i in range(100):
    lines.append([])
    for j in range(100):
        lines[i].append(ax.plot([i,j],color='0.8'))
lines=np.asarray(lines)


##Updating the colors 10 times 
im=[]
for steps in range(10):
    colors=np.random.random(size=(100,100))
    for i in range(100):
        for j in range(100):
            lines[i,j][0].set_color(str(colors[i,j])) 
    plt.draw()
#    im.append(ax)
    plt.pause(.1)
#ani = animation.ArtistAnimation(fig, im, interval=1000, blit=True,repeat_delay=1000)
plt.show()

正如我所说,我想将它与动画并排运行。所以我更喜欢把它做成动画。我认为这至少可以在动画开始后解决滞后问题,但现在我定义它的方式,它不起作用。

【问题讨论】:

  • 如果有任何不清楚的地方,我很乐意澄清。我已经从头开始重写了这个例子,只是为了找到做我想做的事情的最佳方法。
  • 我不想问这个,但对你来说什么是慢的。我运行了你展示的整个代码,它在大约 5 秒内显示了一系列漂亮的图。
  • @Paul,当然,我编辑以澄清你的抱怨。

标签: python numpy matplotlib plot


【解决方案1】:

为此使用LineCollection 是最简单的。这样,您可以将所有颜色设置为单个数组,并且通常可以获得更好的绘图性能。

更好的性能主要是因为集合是在 matplotlib 中绘制大量相似对象的优化方式。在这种情况下,避免使用嵌套循环设置颜色实际上是次要的。

考虑到这一点,尝试更多类似的方法:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
import matplotlib.animation as animation

lines=[]
for i in range(10):
    for j in range(10):
        lines.append([(0, i), (1, j)])

fig, ax = plt.subplots()
colors = np.random.random(len(lines))
col = LineCollection(lines, array=colors, cmap=plt.cm.gray, norm=plt.Normalize(0,1))
ax.add_collection(col)
ax.autoscale()

def update(i):
    colors = np.random.random(len(lines))
    col.set_array(colors)
    return col,

# Setting this to a very short update interval to show rapid drawing.
# 25ms would be more reasonable than 1ms.
ani = animation.FuncAnimation(fig, update, interval=1, blit=True, 
                              init_func=lambda: [col])
# Some matplotlib versions explictly need an `init_func` to display properly...
# Ideally we'd fully initialize the plot inside it. For simplicitly, we'll just
# return the artist so that `FuncAnimation` knows what to draw.
plt.show()

【讨论】:

    【解决方案2】:

    如果您想加快 for 循环,有几种好方法可以做到这一点。对于您正在尝试做的事情,生成器表达式的最佳选择可能是这样的:

    iterator = (<variable>.upper() for <samevariable> in <list or other iterable object>)
    

    (有关这些方面的更多具体信息,请参阅http://www.python.org/dev/peps/pep-0289/https://wiki.python.org/moin/Generators 的文档)

    还有其他非 for 循环的方法来更新颜色,但它们不太可能比生成器快。您可以为这些行创建某种形式的组,然后调用类似:

    lines.update()
    

    所有这些。

    【讨论】:

      猜你喜欢
      • 2021-07-09
      • 2020-04-12
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      • 1970-01-01
      • 2017-04-05
      • 2018-04-08
      相关资源
      最近更新 更多