【matplotlib】PIL(Pillow)とBytesIOを使ってGIFアニメーションを作成する方法[Python]

  • URLをコピーしました!
目次

matplotlib

前回、リスト内包表記の変わった使い方を紹介しました。

今回はPIL(Pillow)とBytesIOを使ってGIFアニメーションを作成する方法を紹介します。

ちなみに前にmatplotlibのグラフを一度pngに保存してから、PIL(Pillow)でGIFアニメーションを作成する方法やffmpegを使ってアニメーションを作成する方法を紹介しました。

今回は、matplotlibからPIL(Pillow)とBytesIOを使って画像を保存せずに直接GIFアニメーションを作成します。

それでは始めていきましょう。

PIL(Pillow)とBytesIOを使って直接GIFアニメーションを作成する方法

今回は簡単な二次関数を使って、グラフ上に一つずつ点を打っていくアニメーションを作成してみました。

プログラム全体としてはこんな感じです。

import matplotlib.pyplot as plt
import io
from PIL import Image

x_list = range(100)
y_list = [x_val**2 for x_val in x_list]

fig = plt.figure()

img_list = []
for x_val, y_val in zip(x_list, y_list):
    plt.xlim(x_list[0], x_list[-1])
    plt.ylim(min(y_list), max(y_list))
    plt.scatter(x_val, y_val, c="tab:blue")
    img_bytes = io.BytesIO()
    plt.savefig(img_bytes, format="png")
    img = Image.open(img_bytes)
    img_list.append(img)
    
img_list[0].save("python-matplotlib92-1.gif", 
save_all=True, append_images=img_list[1:], optimize=True, duration=100, loop=0)

実行結果

上から説明をしていきます。

まずインポートするライブラリは「matplitlib.pyplot」、「io」、「PIL.Image」の三つです。

import matplotlib.pyplot as plt
import io
from PIL import Image

Xの値のリストとYの値のリストを作成します。

今回はXの値は0から100、そしてYの値はその二乗としました。

x_list = range(100)
y_list = [x_val**2 for x_val in x_list]

ここからがグラフを描いていく過程になります。

fig = plt.figure()

img_list = []
for x_val, y_val in zip(x_list, y_list):
    plt.xlim(x_list[0], x_list[-1])
    plt.ylim(min(y_list), max(y_list))
    plt.scatter(x_val, y_val, c="tab:blue")
    img_bytes = io.BytesIO()
    plt.savefig(img_bytes, format="png")
    img = Image.open(img_bytes)
    img_list.append(img)

まずは「fig=plt.figure()」でグラフエリアを作成します。

そして下記の部分でグラフを作成しています。

for x_val, y_val in zip(x_list, y_list):
    plt.xlim(x_list[0], x_list[-1])
    plt.ylim(min(y_list), max(y_list))
    plt.scatter(x_val, y_val, c="tab:blue")

そして作成したグラフをまずはBytesIOを使って、メモリ上にpng画像として保存します。

    img_bytes = io.BytesIO()
    plt.savefig(img_bytes, format="png")

そしてメモリ上に保存したpng画像をPILで読み込み、リストに格納します。

    img = Image.open(img_bytes)
    img_list.append(img)

この様に途中でio.BytesIOを使ってメモリ上に保存することで、画像を出力せずにPILに読み込ませることが可能になります。

そして最後にGIFアニメーションとして保存します。

img_list[0].save("python-matplotlib92-1.gif", 
save_all=True, append_images=img_list[1:], optimize=True, duration=100, loop=0)

PILを使ってGIFアニメーションを作成する方法の詳細はこちらの記事をご覧ください。

次回はリスト内の要素が全てTrueか確認するall関数を紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次