首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Matplotlib函数动画blit慢

Matplotlib函数动画blit慢
EN

Stack Overflow用户
提问于 2013-11-07 18:23:25
回答 1查看 5.8K关注 0票数 4

我在Matplotlib中遇到了慢动画的问题。我是动画的结果从一个模拟,这是最简单的可视化与一个矩形阵列,改变颜色随时间。

按照建议here,我使用闪存只绘制每个帧中变化的矩形的(小部分)。我还试图使用FuncAnimation来实现这一点,但是当使用Blit=True时,脚本运行得慢得多。

我想知道这是否是因为我将所有的矩形返回给FuncAnimation,所以它会重新绘制所有的矩形,即使它们没有改变。有没有办法把不同的艺术家在每一帧传递给FuncAnimation?我试着传递一个已经改变的元组(在“动画”函数中注释掉的块),但是这导致了看似随机的动画帧.

使用:

代码语言:javascript
复制
$ python2 [script].py blit
$ python2 [script].py anim

谢谢!

代码语言:javascript
复制
import sys
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import matplotlib.animation as manim

def animate_data(plot_type):
    """
    Use:
    python2 plot_anim.py [option]
    option = anim OR blit
    """

    # dimension parameters
    Nx = 30
    Ny = 20
    numtimes = 100
    size = 0.5

    if plot_type == "blit":
        # "interactive mode on"
        plt.ion()
    # Prepare to do initial plot
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    ax.set_aspect('equal', 'box')
    ax.xaxis.set_major_locator(plt.NullLocator())
    ax.yaxis.set_major_locator(plt.NullLocator())
    # An array in which to store the rectangle artists
    rects = np.empty((Nx, Ny), dtype=object)
    # Generate initial figure of all green rectangles
    for (i,j),k in np.ndenumerate(rects):
        color = 'green'
        rects[i, j] = plt.Rectangle([i - size / 2, j - size / 2],
                size, size, facecolor=color, edgecolor=color)
        ax.add_patch(rects[i, j])
    ax.autoscale_view()

    # "Old" method using fig.canvas.blit()
    if plot_type == "blit":
        plt.show()
        fig.canvas.draw()
        # Step through time updating the rectangles
        for tind in range(1, numtimes):
            updated_array = update_colors(rects)
            for (i, j), val in np.ndenumerate(updated_array):
                if val:
                    ax.draw_artist(rects[i, j])
            fig.canvas.blit(ax.bbox)

    # New method using FuncAnimate
    elif plot_type == "anim":
        def animate(tind):
            updated_array = update_colors(rects)
#            # Just pass the updated artists to FuncAnimation
#            toupdate = []
#            for (i, j), val in np.ndenumerate(updated_array):
#                if val:
#                    toupdate.append(rects[i, j])
#            return tuple(toupdate)
            return tuple(rects.reshape(-1))
        ani = manim.FuncAnimation(fig, animate, frames=numtimes,
                interval=10, blit=True, repeat=False)
        plt.show()

    return

# A function to randomly update a few rectangles
def update_colors(rects):
    updated_array = np.zeros(rects.shape)
    for (i, j), c in np.ndenumerate(rects):
        rand_val = np.random.rand()
        if rand_val < 0.003:
            rects[i, j].set_facecolor('red')
            rects[i, j].set_edgecolor('red')
            updated_array[i, j] = 1
    return updated_array

if __name__ == "__main__":
    if len(sys.argv) > 1:
        plot_type = sys.argv[1]
    else:
        plot_type = "blit"
    animate_data(plot_type)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-08 05:57:41

每个帧更新600个矩形非常慢,代码中的cbar_blit模式更快,因为您只更新颜色更改的矩形。您可以使用PatchCollection来加速绘图,下面是代码:

代码语言:javascript
复制
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import matplotlib.animation as manim
from matplotlib.collections import PatchCollection

Nx = 30
Ny = 20
numtimes = 100

size = 0.5

x, y = np.ogrid[-1:1:30j, -1:1:20j]

data = np.zeros((numtimes, Nx, Ny))

for i in range(numtimes):
    data[i] = (x-i*0.02+1)**2 + y**2

colors = plt.cm.rainbow(data)

fig, ax = plt.subplots()

rects = []
for (i,j),c in np.ndenumerate(data[0]):
    rect = plt.Rectangle([i - size / 2, j - size / 2],size, size)
    rects.append(rect)

collection = PatchCollection(rects, animated=True)

ax.add_collection(collection)
ax.autoscale_view(True)


def animate(tind):
    c = colors[tind].reshape(-1, 4)
    collection.set_facecolors(c)    
    return (collection,)

ani = manim.FuncAnimation(fig, animate, frames=numtimes,
        interval=10, blit=True, repeat=False)

plt.show()        
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19843700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档