質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.99%

matplotlibのanimationで一枚ごとに違うタイトルを付けたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,040

tera_nsykuh

score 10

機械学習の勉強をしています
線形回帰が進む様子をmatplotlibのanimationにしてみています.
epoch数をタイトルにいれたいのですが,表示されません.

具体的には以下のコードです.

import torch
import torch.nn as nn
import numpy as np

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.animation import PillowWriter

# hyper parameters
input_size = 1
output_size = 1
num_epochs = 200
learning_rate = 0.001

# toy dataset
# 15 samples, 1 features
x_train = np.array([3.3, 4.4, 5.5, 6.71, 6.93, 4.168, 9.779, 6.182, 7.59, 2.167,
                    7.042, 10.791, 5.313, 7.997, 3.1], dtype=np.float32)
y_train = np.array([1.7, 2.76, 2.09, 3.19, 1.694, 1.573, 3.366, 2.596, 2.53, 1.221,
                    2.827, 3.465, 1.65, 2.904, 1.3], dtype=np.float32)
x_train = x_train.reshape(15,1)
y_train = y_train.reshape(15,1)

# linear regression model
class LinearRegression(nn.Module):

    def __init__(self, input_size, output_size):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(input_size, output_size)

    def forward(self, x):
        out = self.linear(x)
        return out

model = LinearRegression(input_size, output_size)

# loss and optimizer
# loss function mean squared error
# optimizer stochastic gradient descent
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)


# Figure Setting
fig = plt.figure()
ims = []

# train the model
for epoch in range(num_epochs):
   inputs = torch.from_numpy(x_train)
   targets = torch.from_numpy(y_train)

   optimizer.zero_grad()
   outputs = model(inputs)
   loss = criterion(outputs, targets)
   loss.backward()
   optimizer.step()

   if (epoch + 1) % 10 == 0:
       print('Epoch [%d/%d], Loss: %.4f' % (epoch + 1, num_epochs, loss.item()))

       predicted = model(torch.from_numpy(x_train)).detach().numpy()
       line, = plt.plot(x_train,predicted,"skyblue")
       tm = plt.title("Epoch = {0}".format(epoch+1))
       ims.append([line,tm])

# save the model
torch.save(model.state_dict(), "model.pkl")

od, = plt.plot(x_train,y_train,"ro")
#plt.title("test")
plt.legend([od,line],["Original Data","Fitted Line"])

ani = animation.ArtistAnimation(fig,ims,interval=50,blit=True,repeat_delay=1000)
plt.show()

print("Save Animation? [y/n]")
should_save_animation = str(input())

if should_save_animation == "y":
    anim.save("anim.gif",writer="pillow")

ArtistAnimationに渡すArtistのリストに問題があると思うのですが,解決策が分かりません.
よろしくお願いいたします.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

FuncAnimation を使うとタイトルも動的に変更できます。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation

fig = plt.figure(figsize=(4, 3))

def plot(data):
    plt.cla()
    x = np.linspace(0, np.pi * 4, 100)
    y = np.sin(x + data)
    plt.plot(x, y, c='b')
    plt.title('data={}'.format(data))

# アニメーションを作成する。
anim = FuncAnimation(fig, plot, frames=100)
anim.save('animation.gif', writer='imagemagick')

# Figure を表示する。
fig.show()

イメージ説明

 追記

Axes.set_title() の返り値 matplotlib.text.Text を Artists として入れてもタイトルはアニメーションできないようです。
代わりに  Axes.text() の返り値ならできるので、これでタイトルをアニメーションできました。

参考
matplotlib artist animation : title or text not changing

# Notebook で inline 表示する場合は以下が必要
%matplotlib nbagg

#import packages
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import ArtistAnimation

x = np.linspace(0, np.pi * 4, 100)

fig, ax = plt.subplots(figsize=(4, 4))
frames = []  # 各フレームを構成する Artist 一覧
for delta in np.linspace(0, np.pi, 30):
    y = np.sin(x + delta)

    # 折れ線グラフを作成する。
    lines = ax.plot(x, y, c='b')
    title = ax.text(0.5, 1.01, 'delta={:.2f}'.format(delta),
                     ha='center', va='bottom',
                     transform=ax.transAxes, fontsize='large')
    frames.append(lines + [title])

# アニメーションを作成する。
anim = ArtistAnimation(fig, frames, interval=500)

# gif 画像として保存する。
anim.save('animation.gif', writer='imagemagick')

# Figure を表示する。
fig.show()

イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/20 16:33

    ArtistAnimationを使って,同様の変更は可能でしょうか?

    キャンセル

  • 2018/11/20 17:39 編集

    追記しました。
    一応できますが、title() ではなく、text() でタイトルを作成する必要があるそうです。

    キャンセル

  • 2018/11/20 17:41

    そもそもtitleがArtistに入らないんですね.
    ご回答頂いた方法を使わせて頂きます.
    ありがとうございました.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る