简体   繁体   中英

Best way to draw a grid with colored squares using FuncAnimation

So I am trying to make a game of life using matplotlib's FuncAnimation function to update the grid I am displaying. However, the process is taking longer and longer, probably because I am not pointing out what I am updating. I am not very familiar with the concept of artists either.

For the moment, my code looks like this :

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()

So what I need is the fastest way to color the squares as well as being able to see the progress live without slowing down. A similar issue has been raised here but I can't manage to adapt it to my code unfortunately...

Thank you very much for your time and help !

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM