2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PillowMatplotlibを使ってアニメーションをやってみました。
作成する図形はマンデルブロ集合というフラクタル図形にしました。

VSCodeのJupyter Notebookでアニメーション表示することができます。
適当なコードですみませんが、多少コメントを付けて貼ります。

アニメーション&フラクタル図形の計算で処理が重めです。N(画素数)とframes(フレーム数)を減らすと軽くなります。

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from IPython import display
from matplotlib import rcParams
from matplotlib.animation import ArtistAnimation

rcParams['animation.embed_limit'] = 2**128 # アニメーションのサイズ上限を変更

# マンデルブロ集合のパラメータ
N = 1000
epsilon = 0.1
center = [-0.53, 0.613]

frames = 100 # フレーム数を100に制限

def fn(z, c):
    return z*z + c

def convergence(c):
    z = 0.0
    i = 0
    while i < 100:
        z = fn(z, c)
        if abs(z) > 2:
            return i
        i += 1
    return i

def display_mandelbrot_set():
    
    grid = np.zeros((N, N), dtype=np.uint8)
    points_x = np.linspace(center[0]-epsilon, center[0]+epsilon, N)
    points_y = np.linspace(center[1]-epsilon, center[1]+epsilon, N)
    
    image = Image.new("RGBA", (N, N), tuple([0, 0, 0, 0]))
    plt.axis("off")
    plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False)
    fig = plt.figure(figsize=(15, 15))
    im = plt.imshow(np.array(image), vmin=0, vmax=100, cmap="Blues_r") # 初期値
    ims = [[im]] # 画像(アニメーションのフレーム)のリスト
    frate = N * N / frames
    i = 0
    for n, rec in enumerate(points_x):
        for m, imc in enumerate(points_y):
            c = rec + imc*1J
            grid[m, n] = convergence(c) # 画像(フレーム)に値を入れる
            if i % frate == 0: # アニメーションのフレーム数を100に制限
                im = plt.imshow(np.array(grid), vmin=0, 
                                vmax=100, cmap="Blues_r",
                                animated=True) # 画像の作成
                ims.append([im]) # 画像を追加
            i += 1
    
    ani = ArtistAnimation(fig, ims, interval=0.1, blit=True, repeat_delay=100)
    html = display.HTML(ani.to_jshtml())
    display.display(html) # Jupyter NotebookのためにHTML形式で表示
    ani.save("mandelbrot_set.gif", writer="pillow") # GIF形式で保存
    plt.close(fig)
   
display_mandelbrot_set()

mandelbrot_set.gif

アニメーション作成処理が重くなってしまったのでフレーム数は100に絞りました。
1ピクセルずつ計算する過程をアニメーションにしている感じになりました。

図形が動くようなアニメーションも作ってみます。

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from IPython import display
from matplotlib import rcParams
from matplotlib.animation import ArtistAnimation

rcParams['animation.embed_limit'] = 2**128
solutions = np.array([2.7693, 0.11535-0.58974J, 0.11535+0.58974J])
N = 300
epsilon = 0.1
center = [-0.530, 0.613]

frames = 100

def fn(z, c):
    return z*z + c

def convergence(c):
    z = 0.0
    i = 0
    while i < 100:
        z = fn(z, c)
        if abs(z) > 2:
            return i
        i += 1
    return i

def display_mandelbrot_set(center:list) -> np.array:
    grid = np.zeros((N, N), dtype=np.uint8)
    points_x = np.linspace(center[0]-epsilon, center[0]+epsilon, N)
    points_y = np.linspace(center[1]-epsilon, center[1]+epsilon, N)
    for n, rec in enumerate(points_x):
        for m, imc in enumerate(points_y):
            c = rec + imc*1J
            grid[m, n] = convergence(c)
    return grid

if __name__ == '__main__':
    image = Image.new("RGBA", (N, N), tuple([0, 0, 0, 0]))
    plt.axis("off")
    plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False)
    fig = plt.figure(figsize=(15, 15))
    im = plt.imshow(np.array(image), vmin=0, vmax=100, cmap="Blues_r")
    ims = [[im]]
    for frame in range(frames):
        grid = display_mandelbrot_set(center) # 画像(フレーム)を取得
        im = plt.imshow(np.array(grid), vmin=0, vmax=100, cmap="Blues_r", animated=True)
        ims.append([im]) # 画像を追加
        center = [x - 0.001 for x in center] # 中心を少しだけずらす
    ani = ArtistAnimation(fig, ims, interval=100, blit=True, repeat_delay=1000)
    html = display.HTML(ani.to_jshtml())
    display.display(html)
    ani.save("mandelbrot_set.gif", writer="pillow")
    plt.close(fig)

mandelbrot_set.gif

これは中心centerを少しずつ動かしているだけですが、アニメーションらしくなりました。

matplotlib 3.9.1
pillow 10.4.0


参考)マンデルブロ集合のコードをお借りました

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?