首页 > 解决方案 > 使用 FuncAnimation 绘制带有彩色方块的网格的最佳方法

问题描述

所以我正在尝试使用 matplotlib 的 FuncAnimation 函数来更新我正在显示的网格。然而,这个过程花费的时间越来越长,可能是因为我没有指出我正在更新什么。我对艺术家的概念也不是很熟悉。

目前,我的代码如下所示:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import random as rd
import matplotlib.animation as animation
from time import process_time


Ln = 100     # length
La = 10     # width

data = np.ones((Ln, La)) * np.nan   # matrix filled with 0 containing the squares to be colored
pause = False       # puts in pause when clicking
Case = [(i, j) for i in range(Ln) for j in range(La)] # squares of the grid
Case = dict(zip([i for i in range(La*Ln)], Case))


def randometre(a):

    '''
    Colors a square.
    '''

    while Case:
        if not pause:
            xx, yy = Case.pop(rd.choice(list(Case.keys())))       # colors the next square in a random order
            data[xx, yy] = 1    # square that is being colored
            ax.fill_between([xx, xx + 1], [yy], [yy + 1], color=C)
        break   # to see the coloring process
    return


def on_click(event):
    global pause
    pause ^= True

# random color generation
C = '#%02X%02X%02X' % (rd.randint(0,255), rd.randint(0,255), rd.randint(0,255))

xx = 0
yy = 0


# plotting
fig = plt.figure()
ax = fig.add_subplot(111)

fig.canvas.mpl_connect('button_press_event', on_click)

# drawing grid and squares
for y in range(La + 1):
    ax.plot([0, Ln], [y, y], lw=2, color='k')
for x in range(Ln + 1):
    ax.plot([x, x], [0, La], lw=2, color='k')



# loop coloring squares
ani = animation.FuncAnimation(fig, randometre, blit=False, interval=10, repeat=False, frames=La*Ln)
ax.axis('off')
plt.show()

所以我需要的是为方块着色的最快方法,并且能够在不放慢速度的情况下实时查看进度。此处提出了类似的问题,但不幸的是我无法将其调整为我的代码......

非常感谢您的时间和帮助!

标签: pythonmatplotlib

解决方案


You should use blit=True, I did two modifications to your code. Now is fast.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import random as rd
import matplotlib.animation as animation
from time import process_time


Ln = 100     # length
La = 10     # width

data = np.ones((Ln, La)) * np.nan   # matrix filled with 0 containing the squares to be colored
pause = False       # puts in pause when clicking
Case = [(i, j) for i in range(Ln) for j in range(La)] # squares of the grid
Case = dict(zip([i for i in range(La*Ln)], Case))


def randometre(a):

    '''
    Colors a square.
    '''

    while Case:
        if not pause:
            xx, yy = Case.pop(rd.choice(list(Case.keys())))       # colors the next square in a random order
            data[xx, yy] = 1    # square that is being colored
            poly = ax.fill_between([xx, xx + 1], [yy], [yy + 1], color=C)
        break   # to see the coloring process
    return poly, # must return something to make blit=True to work


def on_click(event):
    global pause
    pause ^= True

# random color generation
C = '#%02X%02X%02X' % (rd.randint(0,255), rd.randint(0,255), rd.randint(0,255))

xx = 0
yy = 0


# plotting
fig = plt.figure()
ax = fig.add_subplot(111)

fig.canvas.mpl_connect('button_press_event', on_click)

# drawing grid and squares
for y in range(La + 1):
    ax.plot([0, Ln], [y, y], lw=2, color='k')
for x in range(Ln + 1):
    ax.plot([x, x], [0, La], lw=2, color='k')



# loop coloring squares, blit=True
ani = animation.FuncAnimation(fig, randometre, blit=True, interval=10, repeat=False, frames=La*Ln)
ax.axis('off')

推荐阅读