- 締切済み
matplotlibのグラフgif動画の背景透過法
現在、以下の解説サイトを参考に、 タイマーカウントありのグラフ動画の作成をArtistAnimationにて試みています。 https://www.yutaka-note.com/entry/matplotlib_artist_anim 「plt.show()」による表示だけでなく、gif動画で自動保存したいため、 参考サイトどおり以下のコードを末尾に追加しています。 anim.save("ファイル名.gif", writer="pillow") ただ、背景(グラフ領域と余白部分)を透明化(透過)させたいため、 以下のコードをグラフ領域の作成直後に追加しています。 fig.patch.set_alpha(0.0) すると、自動保存されたgifファイルは、背景の透明化はされているものの、 タイマー文字ならびにグラフ枠線や軸タイトルといったレイアウトが全て上書きされて出力されてしまいました。 (画像参照、タイマー文字は潰れ、グラフレイアウトはジャギーのようになっています。) 「plt.show()」での表示はきちんと背景が透明化された上で想定通りの挙動を示しているため、 原因としては「anim.save()」の部分だと考えているのですが、 色々と試行錯誤しても想定通りの挙動(上書きされずに透明化)が叶いません。 pillowライブラリの構造の関係で無理筋なのかもしれませんが、 gifファイル自動保存の前提を崩さない上で、上手いコーディング方法をご存じの方がもしおられましたら、 教えていただけますと助かります。 (出力後の別途の画像コンバートや、ffmpeg等の外部ツールを入れてのMP4出力は考えていません。 できるだけ簡便な手法を望んでいます。) 【以下、問題としているサンプルコード】 # 1. 必要なモジュールの読み込み import numpy as np from matplotlib import pyplot as plt from matplotlib.animation import ArtistAnimation # 2.グラフ領域の作成 fig, ax = plt.subplots() fig.patch.set_alpha(0.0) #背景部分の透明化 # 3. アニメーション要素のリスト artists = [] for i in range(100): x = np.linspace(0, 4*np.pi) y = np.sin(x - i/100 * 2*np.pi) # アニメーション化する要素の準備 my_line, = ax.plot(x, y,"blue") my_text = ax.text(0, y[0], " ? inlet", color="darkblue", size ="large") my_title = ax.text( 4.5, 1.15, f"Count = {i}", size="xx-large") # アニメーション化する要素をリスト化 artists.append([my_line, my_text, my_title]) # 4. アニメーション化 anim = ArtistAnimation(fig, artists, interval=50) plt.show() anim.save("ファイル名.gif", writer="pillow") #透明化はされるがgifファイル上で文字が上書きされる
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- asciiz
- ベストアンサー率70% (6803/9674)
GIF画像の透明化と言うのは、定義された色パレットのうち、指定した1色を透明として扱う、と言う方式であるため、そのままではタイマー数字が重なって行くのは当然の動作となります。 ライブラリと言うよりは、「GIF画像の仕様」の話となります。 それを避けるために、タイマー数字の背景に別の色の箱を書いて不透明化してはどうでしょう。 「Count=」の文字や、軸数値においても中間色が重なってジャギーが出てしまうのも同じ問題なので、そこの背景色として真っ白ではなく、ほんのわずかなグレー等を置いておけば、透明化されずに綺麗な文字が出ると思います。