Plotly グラフのアニメーション#

※記事内に商品プロモーションを含むことがあります。

公開日

Pythonのインタラクティブなグラフを描画できるライブラリPlotlyにて、グラフのアニメーションを描画する方法を解説します。

Plotlyには、高水準のAPIであるPlotly Expressと呼ばれるものもありますが、 この記事では細かい調節ができるgraph_objectsを対象としています。

アニメーションの基礎#

棒グラフのアニメーションの簡単な例を示します。 "Play"というボタンを押すと、棒グラフが伸びるアニメーションが再生されます。

import plotly.graph_objects as go

layout = go.Layout(
    yaxis={"range": [0, 10]},
    updatemenus=[
        {
            "type": "buttons",
            "buttons": [
                dict(label="Play", method="animate", args=[None]),
            ],
        },
    ],
)

fig = go.Figure(
    data=[go.Bar(x=["Alice", "Bob"], y=[1, 2])],
    layout=layout,
    frames=[
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[1, 2])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[2, 4])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[3, 6])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[4, 8])]),
    ],
)

fig.show()

上記の例を解説します。

まず、以下の通りgo.Layoutupdatemenus属性にアニメーションを再生するボタンを設定します。

  • label (str): ボタンのラベル

  • method (str): アニメーションを再生するため、"animate"を指定

  • args: [None]とすると、通常のアニメーションとなります。

layout = go.Layout(
    yaxis={"range": [0, 10]},
    updatemenus=[
        {
            "type": "buttons",
            "buttons": [
                dict(label="Play", method="animate", args=[None]),
            ],
        },
    ],
)

次に、go.Figureframes属性に、アニメーションで表示するグラフを定義します。 このframes属性にはgo.Frameインスタンスのリストを与えます。

fig = go.Figure(
    data=[go.Bar(x=["Alice", "Bob"], y=[1, 2])],
    layout=layout,
    frames=[
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[1, 2])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[2, 4])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[3, 6])]),
        go.Frame(data=[go.Bar(x=["Alice", "Bob"], y=[4, 8])]),
    ],
)

アニメーションの再生速度#

アニメーションの再生速度を変更する場合、updatemenusargs{"frame": {"duration": 50}}のような辞書を追加します。 数値を大きくすると、ゆっくりと再生されます。

layout = go.Layout(
    xaxis={"range": [0, 2*np.pi]},
    yaxis={"range": [-1.5, 1.5]},
    updatemenus=[
        {
            "type": "buttons",
            "buttons": [
                dict(
                    label="Play",
                    method="animate",
                    args=[None, {"frame": {"duration": 50}}]),
            ],
        },
    ],
)

複数プロットのアニメーション#

次に、複数のプロットに対するアニメーションを例示します。 正弦波のグラフ上で点を動かすアニメーションです。

import numpy as np

x = np.arange(start=0, stop=2*np.pi, step=0.1)
sin_y = np.sin(x)

layout = go.Layout(
    xaxis={"range": [0, 2*np.pi]},
    yaxis={"range": [-1.5, 1.5]},
    updatemenus=[
        {
            "type": "buttons",
            "buttons": [
                dict(
                    label="Play",
                    method="animate",
                    args=[None, {"frame": {"duration": 50}}]),
            ],
        },
    ],
)

frames = [
    go.Frame(
        data=[go.Scatter(x=[x[i]], y=[sin_y[i]])],
        traces=[1],
    )
    for i in range(len(x))
]

fig = go.Figure(
    data=[
        go.Scatter(x=x, y=sin_y, mode="lines"),
        go.Scatter(x=[x[0]], y=[sin_y[0]], mode="markers", marker=dict(size=15)),
    ],
    layout=layout,
    frames=frames,
)

fig.show()

変数framesでは、リスト内包表記でgo.Frameインスタンスのリストを作成しています。 ここでtraces=[1]としているのは、2つ目のグラフ(赤点のグラフ)を更新することを示しています。

go.Figuredataには2つのグラフを定義しています。 1つ目は青い折れ線グラフ(mode="lines")、2つ目は赤点のグラフ(mode="markers")です。

参考サイト#