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.Layout
のupdatemenus
属性にアニメーションを再生するボタンを設定します。
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.Figure
のframes
属性に、アニメーションで表示するグラフを定義します。
この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])]),
],
)
アニメーションの再生速度#
アニメーションの再生速度を変更する場合、updatemenus
のargs
に{"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.Figure
のdata
には2つのグラフを定義しています。
1つ目は青い折れ線グラフ(mode="lines"
)、2つ目は赤点のグラフ(mode="markers"
)です。