10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Jupyter / ipywidgetsで簡易アニメーションプレイヤーを実装する

Last updated at Posted at 2018-07-07

概要

Jupyter / ipywidgetsで__簡易__アニメーションプレイヤーを実装しました.
以下のような形でアニメーションを再生できます.

earth.gif

そもそものモチベーションとしては,「連番画像を手軽にJupyterで再生したい」でした.
方法としてmatplotlib.animationが真っ先に浮かんだのですが,これを用いてスムーズに実装できた事が私はあまり無く,時間を注ぐような部分でもなかったので,今回はipywidgets単体でのシンプルな実装を試みました.

実装

以降のコードでは,連番画像は変数 movie に入っており,そのshapeは (t, h, w, c) であるものとします.

import os
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
from ipywidgets import IntSlider
from ipywidgets import Play, jslink, HBox
from ipywidgets import interactive_output

まず本体のコードになります.今回は ipywidgetsPlay, IntSlider, interactive_output などを組み合せてプレイヤーを実装しています.

def plotPlayer(plot, start, end, interval=250, step=1):
    play = Play(min=start,
                max=end,
                step=step,
                interval=interval,
                description="Press play",
                disabled=False
                )
    slider = IntSlider(min=start, max=end)
    jslink((play, 'value'), (slider, 'value'))
    controller = HBox([play, slider])
    output = interactive_output(plot, {'t': slider})
    return display(controller, output)

Play は再生・一時停止・停止・リピートといったようなプレイヤー部分を,IntSlider はその名の通り,スライダー部分となっています.jslink はプレイヤーとスライダーの同期を取っています.

各引数の意味や,他の Widget については, 公式ドキュメント がコード例もついていてわかりやすいのでそちらを参照ください.このコードも殆どそれに沿ったものになっています.

最後の2行で,ここまでで作成したWidgetと,画像表示部分を合わせて表示しています.innteractive_output() の引数にある plot ですが,これはアニメーションさせたいものに合わせて自分で作る必要のある関数です.今回は画像表示のために以下のような関数を用意しています.至って単純なプロットを行う関数ですが,注意点としては,引数の tinnteractive_output() の第2引数と対応しているという点です.ここを合わせておかないと,全てが同期して動いてくれません.

def plotMovie(t, figsize=(12, 8)):
    plt.figure(figsize=figsize)
    plt.imshow(movie[t])
    plt.grid(False)
    plt.show()

最後に,以下のコードを実行すれば,最初のgifのようにプレイヤーが起動します.

# np.shape(movie) -> (t, h, w, c)
plotPlayer(plotMovie, 0, len(movie)-1, interval=250)

ちなみに画像である必要はなく,plotMovie() を変更することでグラフなども再生することが可能です.

def plotLine(t, figsize=(16, 8)):
    plt.figure(figsize=figsize)
    plt.xlim(0, 10)
    plt.ylim(-5, 5)
    plt.plot(x[:t], y[:t])
x = np.arange(0, 100, 0.1)
y = np.sin(x) + np.random.randn(len(x))

plotPlayer(plotLine, x[0], x[-1], interval=100)

sin.gif

最後に

gifを見て頂けると分かるかと思いますが,上記の私の実装では,どうしても「カクつき(ラグ)が生じる」「保存はできない」という問題点が生じており,再生スピード(interval)を上げると何とも微妙な感じになってしまいます.(もっとも私の本来の目的の上では特に問題ではなかったのですが,)これがタイトルでも"簡易"と入れている理由になります.

参考リンク

10
3
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
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?