简体   繁体   中英

Redraw matplotlib.pyplot.imshow in place using Jupyter

I am trying to draw these pretty boxes but instead of drawing them vertically, I want each box to overwrite the previous, so it looks like one box with changing colours every .5 seconds

I am using Jupyter notebooks and Python 3.6.

I have read about 50 similar questions and answers but can't get it to display as desired. Anyone who can help please?

from PIL import Image
import random
import time
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow, show, clf

sq_size = 20
num_squares = 5
im_size = sq_size * num_squares

im = Image.new('RGB', (im_size, im_size), color = 'white')

pix = im.load()

#Create new colourful boxes 4 times
for _ in range(4):

    startx, starty = 0, 0

    #move to the right place to plot each small square
    for i in range(num_squares):
        startx += sq_size
        for j in range(num_squares):
            starty += sq_size
            rshade = np.random.randint(0, 256)
            gshade = np.random.randint(0, 256)
            bshade = np.random.randint(0, 256)

            #plot each small square
            for x in range(sq_size):
                for y in range(sq_size):
                    value = (rshade, gshade, bshade)
                    pix[(startx + x) % im_size, (starty + y) % im_size] = value 

    plt.imshow(im)
    plt.show()

    time.sleep(.5)

Currently this plots as follows...

在此处输入图片说明

but I want each box to overwrite the previous, so it looks like one box with changing colours every .5 seconds

OK. I found a solution. it is based on https://matplotlib.org/examples/animation/dynamic_image2.html

from PIL import Image
import random
import time
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow, show
import matplotlib.animation as animation

%matplotlib notebook

def next_shape(im, num_squares, sq_size):
    pix = im.load()

    #initialise plot location
    startx, starty = 0, 0

    for i in range(num_squares):
        startx += sq_size
        for j in range(num_squares):
            starty += sq_size
            rshade = np.random.randint(0, 256)
            gshade = np.random.randint(0, 256)
            bshade = np.random.randint(0, 256)

            for x in range(sq_size):
                for y in range(sq_size):
                    value = (rshade, gshade, bshade)
                    pix[(startx + x) % im_size, (starty + y) % im_size] = value 

    #return list of pixel tuples
    return list(im.getdata())

# First set up the figure, the axis, and the plot element we want to animate
sq_size = 20
num_squares = 5

#create a figure to animate
fig = plt.figure()

#create the image withi the figure to animate
im_size = sq_size * num_squares
im = Image.new('RGB', (im_size, im_size))

#create a list to store all the images in the format of a list of RGB pixels
im_list_pix = []

#generate a bunch of images in the form of a list of RGB pixels
for pic in range(10):
    im_list_pix.append(next_shape(im, 5, 20))

#create a list to store images converted from RGB pixel tuples to image format
img_array = []

#convert list of pixel tuples back to image
for i, v in enumerate(im_list_pix):
    im = Image.new('RGB', (100, 100))
    #put the pixel data into the image container
    im.putdata(im_list_pix[i])

    im = plt.imshow(im)
    img_array.append([im])  

ani = animation.ArtistAnimation(fig, img_array, interval=500)

plt.show()

It took me a long time to work out the square brackets in ...

img_array.append([im])

... is crucial. It must be the way matplotlib.animate parses the list.

I hope this is useful for others wanting to pay with matplot.animate and have some fun creating art.

PS - thank you to the commenters who pointed me towards matplotlib.animate and thanks also to the author of this great blog post that gave me some clues and also shows how far you can push this stuff http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/

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