【plotly】複数のグラフを一度にプロットする方法[Python]

  • URLをコピーしました!
目次

plotly

前回、HTML上でインタラクティブなグラフ描写ができるライブラリplotlyでY軸を左右で2軸にする方法とX軸を上下で2軸にする方法を解説しました。

今回、複数のグラフを一度にプロットする方法を試してみましょう。

ということで今回はこんな感じで、Yの値が10倍ずつ違う4つのデータを用意してみました。

import random
import plotly.graph_objects as go

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

graph=[graph1, graph2, graph3, graph4]

fig = go.Figure(data=graph)

with open('./plotly10-1.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

これらを別々のグラフとして表示してみましょう。

複数のグラフを一度にプロットする方法

複数のグラフを一度にプロットするには以下の3段階を踏みます。

  1. 「fig = go.Figure().set_subplots(rows=行の数, cols=列の数)」でプロットのエリアを作成
  2. 「graph = go.Scatter(x=Xの値のリスト,y=Yの値のリスト)」でグラフを作成
  3. 「fig.append_trace(グラフデータ, row=行の場所, col=列の場所)」でグラフをプロットエリアに配置

ということで試してみましょう。

import random
import plotly.graph_objects as go

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

with open('./plotly10-2.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

左上が1番のデータ(row=1、col=1)、右上が2番のデータ(row=1、col=2)、左下が3番のデータ(row=2、col=1)、右下が4番のデータ(row=2、col=2)となりました。

サブプロットにタイトルを設定

次にサブプロット(それぞれのグラフ)に別々のタイトルをつけてみましょう。

その場合は「go.Figure().set_subplots()」に「subplot_titles=(各グラフのタイトルのタプル)」を追加します。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2, subplot_titles=('10', '100', '1000', '10000'))

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

with open('./plotly10-3.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

縦に並んだグラフでX軸を共有する方法

縦に並んだグラフで同じX軸を使うこともよくあります。

その場合は「go.Figure().set_subplots()」のオプションに「shared_xaxes=True」を追加します。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2, shared_xaxes=True)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

with open('./plotly10-4.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

横に並んだグラフでY軸を共有する方法

また横に並んだグラフで同じY軸を使うことも結構あります。

その場合は「go.Figure().set_subplots()」のオプションに「shared_yaxes=True」を追加します。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2, shared_yaxes=True)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

with open('./plotly10-5.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

X軸、Y軸のラベルを追加

X軸、Y軸のラベルを追加するには「fig.update_layout()」に「(xaxisグラフの番号=dict(title=’X軸のラベル’)」、「yaxisグラフの番号=dict(title=’Y軸のラベル’)」とします。

この際、グラフの番号は左上が1で右に行くと数字が増え、右端までいったら、一段降りて左端から数えるという感じのようです。

ということでそれぞれのグラフにX軸ラベル、Y軸ラベルを追加するとこんな感じです。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

fig.update_layout(xaxis1=dict(title='X-Axis1'), yaxis1=dict(title='Y-Axis1'),
                 xaxis2=dict(title='X-Axis2'), yaxis2=dict(title='Y-Axis2'),
                 xaxis3=dict(title='X-Axis3'), yaxis3=dict(title='Y-Axis3'),
                 xaxis4=dict(title='X-Axis4'), yaxis4=dict(title='Y-Axis4'))

with open('./plotly10-6.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

ちなみに前に軸ラベルは「fig.update_layout(xaxis=dict(title=’X軸のラベル’), yaxis=dict(title=’Y軸のラベル’))」という書き方を勉強しました。

これだとどうなるのか試してみましょう。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

fig.update_layout(xaxis=dict(title='X-Axis'),
                 yaxis=dict(title='Y-Axis'))

with open('./plotly10-7.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

左上だけにX軸ラベル、Y軸ラベルが表示されました。

また軸ラベルを表示するもう一つの方法として、「fig.update_xaxes(title=’X軸ラベル’)」、もしくは「fig.update_yaxes(title=’Y軸ラベル’)」という書き方も勉強しました。

この場合はどうなるのか試してみましょう。

import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

x4_val = [i for i in range(data_points)]
y4_val = [random.randrange(10000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)
graph4 = go.Scatter(x=x4_val,y=y4_val)

fig = go.Figure().set_subplots(rows=2, cols=2)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)
fig.append_trace(graph4, row=2, col=2)

fig.update_xaxes(title='X-Axis')
fig.update_yaxes(title='Y-Axis')

with open('./plotly10-8.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

全てのグラフで同じX軸ラベル、Y軸ラベルが表示されました。

「fig.layout_update()」を使う場合と、「fig.update_xaxes(title=’X軸ラベル’)」、もしくは「fig.update_yaxes(title=’Y軸ラベル’)」を使う方法で違いが出てきたので注意です。

複数のグラフのレイアウトを変更する方法

ここからははさらに複数のグラフを一度にプロットした時のレイアウトをいじってみましょう。

どういうことかというと、例えばこんな感じで複数のグラフを配置してみましょうということ。

特定のグラフを目立たせたかったり、奇数個のグラフを並べる時に重宝しそうです。

まずは基本となるプログラムからです。

import random
import plotly.graph_objects as go

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)

fig = go.Figure().set_subplots(rows=2, cols=2)

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=1)

with open('./plotly11-1.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

実行結果

前回勉強した方法で2列、2行のエリアに3つのグラフを表示してみましたが、1箇所欠けてしまい、このままでは不恰好です。

それではこれをレイアウトしていきましょう。

左に1つ、右に2つ

まずは左側の列に1つのグラフ、右側の列に2つのグラフをプロットしてみましょう。

つまりこんな感じのプロットです。

このように複数のグラフを違うサイズでプロットする場合、「.set_subplot()」のオプションに「specs」を追加します。

そしてこの「specs」の書き方は二次元配列となります。

まず2行2列のプロットでの基本の書き方としてはこんな感じ。

specs=[[{},{}],[{}, {}]]

「{}」の部分がグラフの位置で、この場所はグラフが配置されることを示しています。

そしてグラフが配置されない場所は「None」と表記します。

今回、左下(1列2行目)はグラフが配置されませんので、こうなります。

specs=[[{},{}],[None, {}]]

そして次に左上(1行1列目)が縦に2行分のエリアを使用することを記述します。

その場合「{‘rowspan: 2’}」と記述します。

つまり「specs」の記述はこうなります。

specs=[[{'rowspan: 2’},{}],[None, {}]]

あとは「add_trace()」での位置を間違えないように注意します。

左のグラフは1行1列目なので「fig.append_trace(graph1, row=1, col=1)」、右上のグラフは1行2列目なので「fig.append_trace(graph2, row=1, col=2)」、右下のグラフは2行2列目なので「fig.append_trace(graph3, row=2, col=2)」となります。

それでは試してみましょう。

import random
import plotly.graph_objects as go

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)

fig = go.Figure().set_subplots(rows=2, cols=2, specs=[[{'rowspan': 2},{}],[None, {}]])

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=1, col=2)
fig.append_trace(graph3, row=2, col=2)

with open('./plotly11-2.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

実行結果

上に1つ、下に2つ

次に上に1つのグラフ、下に2つのグラフをプロットしてみましょう。

つまりこんな感じのグラフです。

基本的な考え方は先ほどの左に1つ、右に2つのグラフを同じです。

ただ今回は上の行が2列にまたがったグラフなので、「rowspan」の代わりに「colspan」を使います。

つまり「specs」の書き方としてはこんな感じになります。

import random
import plotly.graph_objects as go

data_points = 100

x1_val = [i for i in range(data_points)]
y1_val = [random.randrange(10) for _ in range(data_points)]

x2_val = [i for i in range(data_points)]
y2_val = [random.randrange(100) for _ in range(data_points)]

x3_val = [i for i in range(data_points)]
y3_val = [random.randrange(1000) for _ in range(data_points)]

graph1 = go.Scatter(x=x1_val,y=y1_val)
graph2 = go.Scatter(x=x2_val,y=y2_val)
graph3 = go.Scatter(x=x3_val,y=y3_val)

fig = go.Figure().set_subplots(rows=2, cols=2, specs=[[{'colspan': 2},None],[{}, {}]])

fig.append_trace(graph1, row=1, col=1)
fig.append_trace(graph2, row=2, col=1)
fig.append_trace(graph3, row=2, col=2)

with open('./plotly11-3.txt', 'w') as f:
     f.write(fig.to_html(include_plotlyjs='cdn',full_html=False))

実行結果

これで行、列ともに複数行、複数列にまたがったグラフをプロットできるようになりました。

さてこれでPlotlyに関しては基本的なことを学び、いろいろなことができるようになったと思います。

ということでとりあえず連載はここまでとして、また何かあれば随時記事をアップしていきたいと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次