plotlyを使って,3次元surfaceの作図を行いたいと思います。
plotlyは作図後もグラフの拡大縮小や視点を変えたりできるので,3次元グラフとの相性抜群だと思います。
この記事の目標は以下の通りです。
3次元surfaceのカラーを変更する
背景や軸周りの設定を行う
等高線との併記を行う
目標とするグラフは以下の通りです。
plotlyで作図することで,ぐるぐる動かすことができます!
*このグラフのコードは,最後のまとめにあります。一括でコピペしたい場合は,そちらを参考にしてください。
以下の目次に従い,一つ一つ設定を行っていきます。
ライブラリの読み込み,データの作成
ライブラリには,plotlyとnumpyを使用します。
numpyはグラフに作図する関数を定義するために使うので,描写したいデータに応じてpandasなど追加してください。
グラフの描写自体はplotlyだけで可能です。
import plotly.graph_objects as go
import numpy as np
今回,3Dグラフを作成するにあたり,↓の関数を使い練習します。
$$ z = \sin(x) +\sin(y) $$
この関数について,xとyをそれぞれ0〜4\(\pi\)までの範囲で動かします。
関数で定義すると下記のようになります。
# 関数の定義
def func(x, y):
return np.sin(x) + np.sin(y)
# 関数の値域
x = np.linspace(0, np.pi * 4, 10)
y = np.linspace(0, np.pi * 4, 10)
X, Y = np.meshgrid(x, y)
この関数を使った等高線の作図は,以下の記事にまとめてありますので,よろしければ違いを確認してみてください。状況によっては,等高線の方が伝わりやすい場合もあるかもしれませんので。
3次元Surfaceの作成
ここからは3次元Surfaceの作図を行います。公式HPはこちらを参考にしてください。
3次元Surfaceのグラフは以下の通りです。
先ほどの関数\( z = \sin(x) +\sin(y) \)を使用しています。
*上記は画像です
コードは以下の通りです。関数を併せて定義しています。
# 関数の定義
def func(x, y):
return np.sin(x) + np.sin(y)
# 関数の値域
x = np.linspace(0, np.pi * 4, 10)
y = np.linspace(0, np.pi * 4, 10)
X, Y = np.meshgrid(x, y)
#作図
fig=go.Figure()
fig.add_trace(go.Surface(z=func(X,Y),
x=x,
y=y,
colorscale='jet'
))
fig.show()
まず2〜7行目にて,関数とその値域を0〜4πの範囲で定義しています。
いくつか方法はありますが,グラフの作成の大まかな流れとしては,
1. fig = go.Figure() : グラフ(インスタンス)の作成
2. fig.add_trace() : グラフデータの設定
3. fig.update_layout(): グラフの軸やタイトルの設定
(3次元グラフの軸の設定はfig.update_scenes()でもOK)
4. fig.show() : グラフの表示
5. ( fig.write_html() ) : グラフ保存
です。
ここでは,9〜14行目のfig.add_trace(go.Surface(…))で等高線の作図を行なっています。
fig.add_trace(go.Surface(z= <VALUE>,
x= <VALUE>,
y= <VALUE>,
colorscale= <VALUE>
))
z = ○○○ | z座標のデータ |
x = ○○○ | x座標のデータ |
y = ○○○ | y座標のデータ |
colorscale = ○○○ | カラーバーで使う配色の設定 ‘rainbow’, ‘hot’, ‘ice’などから選択,詳しくはこちら |
colorscaleの変更
colorscaleの変更によって,グラフの印象がどのように変わるか確認したいと思います。
ここでは,‘rainbow’, ‘hot’, ‘ice’の3つを試します。
*下記はページ画像です。
背景や軸周りの設定
次に,x軸・y軸・z軸それぞれについて背景や軸周りの設定を行います。
作成するグラフは以下です。
*上記は画像です
コードは以下の通りです。
fig=go.Figure()
fig.add_trace(go.Surface(z=func(X,Y),
x=x,
y=y,
colorscale='jet'
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(-2,2),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Z',font=dict(color='black',size=18))
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='X',font=dict(color='black',size=18))
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Y',font=dict(color='black',size=18))
))
fig.show()
背景や軸周りの設定は,fig.update_scenes(…)で行うことができます(公式HPはこちら)。
z軸,x軸,y軸について,zaxis=dict(…), xaxis=dict(…), yaxis=dict(…)で設定しますがdict(…)の中身は同じです。
以下では, zaxis=dict(…)についてまとめています。
fig.update_scenes(zaxis=dict(backgroundcolor= <VALUE>,
gridcolor= <VALUE>,
gridwidth= <VALUE>,
linecolor= <VALUE>,
range= <VALUE>,
dtick= <VALUE>,
mirror= <VALUE>,
tickfont=dict(color= <VALUE>, size= <VALUE>),
title=dict(text= <VALUE>,
font=dict(color= <VALUE>,size= <VALUE>))
))
backgroundcolor=○○○ | 背景の色 | ||
gridcolor=○○○ | グリッド線の色 | ||
gridwidth=○○○ | グリッド線の太さ | ||
linecolor=○○○ | 軸線の色 | ||
range=○○○ | 軸の表示範囲 | ||
dtick=○○○ | 軸の目盛り間隔 | ||
mirror=○○○ | ‘True’で反対の軸に設定が反映される | ||
tickfont=dict(…) | color=○○○ | 軸の数値の色 | |
size=○○○ | 軸の数値のサイズ | ||
title=dict(…) | text=○○○ | 軸のラベル名 | |
font=dict(…) | color=○○○ | 軸のラベル名の色 | |
size=○○○ | 軸のラベル名のサイズ |
色の変更
上記では,zaxis/xaxis/yaxis で背景色backgroundcolorが全て’white’だったので対応がわかりづらいです。
そこで,軸ごとに背景色を変えてみます。
- zaxis=dict(backgroundcolor=’lightblue’)
- zaxis=dict(backgroundcolor=’lightyellow’)
- yaxis=dict(backgroundcolor=’lightcoral’)
とすると以下のグラフが得られます。
*上記は画像です
等高線の併記
最後に,z軸平面に等高線を併記する方法をみてみます。
コードは以下の通りです。
#作図
fig=go.Figure()
fig.add_trace(go.Surface(z=func(X,Y),
x=x,
y=y,
colorscale='jet'
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(-2,2),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Z',font=dict(color='black',size=18))#family
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='X',font=dict(color='black',size=1))#family
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Y',font=dict(color='black',size=18))#family
))
#z軸平面に等高線の併記
fig.update_traces(contours_z=dict(show=True,
usecolormap=False,
project_z=True,
color='gray',
start=-2,
end=2,
size=0.1))
fig.show()
z軸平面に等高線を併記には,51-57行目のcontours_z=dict(…)で行います。
contours_z=dict(…)の詳細は以下の通りです。
各項目は下表を参照してください。
fig.update_traces(contours_z=dict(show= <VALUE>,
usecolormap= <VALUE>,
project_z= <VALUE>,
color= <VALUE>,
start= <VALUE>,
end= <VALUE>,
size= <VALUE>))
show=○○○ | “True”, “False”のどちらかを選択 等高線の表示をする /しない を設定できる |
usecolormap=○○○ | “True”, “False”のどちらかを選択 等高線の色を3次元surfaceのcolorscaleに合わせる/別に設定する |
project_z=○○○ | “True”, “False”のどちらかを選択 z軸平面に等高線を投影する/しない |
color=○○○ | 等高線の色の設定(usecolormap= Falseのとき) |
start=○○○ | 等高線の表示範囲の始点 |
end=○○○ | 等高線の表示範囲の終点 |
size=○○○ | 等高線の表示間隔 |
usecolormap,project_zの”True” / ”False”の使い方について,次でもう少し詳しくみてます。
等高線の色を3次元surfaceの配色に合わせる(usecolormap=True)
usecolormap=Trueとすると,等高線は3次元surfaceのcolorscaleと同じ配色になります。
*上記はページの読み込み速度軽減のためpngです。
z軸平面に等高線を表示しない(project_z=False)
project_z=Falseとすることで,z軸平面に等高線を表示をしなくなります。
*上記はページの読み込み速度軽減のためpngです。
まとめ
3次元surfaceの作図方法についてみてきました。
グラフの作成の大まかな流れとしては,
1. fig = go.Figure() : グラフ(インスタンス)の作成
2. fig.add_trace() : グラフデータの設定
3. fig.update_layout(): グラフの軸やタイトルの設定
(3次元グラフの軸の設定はfig.update_scenes()でもOK)
4. fig.show() : グラフの表示
5. ( fig.write_html() ) : グラフ保存
です。
以下で,本記事で紹介した3次元surfaceの設定項目を一覧でまとめています。
fig=go.Figure()
# 3次元surface
fig.add_trace(go.Surface(z= <VALUE>,
x= <VALUE>,
y= <VALUE>,
colorscale= <VALUE>
))
# 3次元surface 軸周りの設定
fig.update_scenes(zaxis=dict(backgroundcolor= <VALUE>,
gridcolor= <VALUE>,
gridwidth= <VALUE>,
linecolor= <VALUE>,
range= <VALUE>,
dtick= <VALUE>,
mirror= <VALUE>,
tickfont=dict(color= <VALUE>, size= <VALUE>),
title=dict(text= <VALUE>,
font=dict(color= <VALUE>,size= <VALUE>))
))
# 3次元surface 等高線の併記
fig.update_traces(contours_z=dict(show= <VALUE>,
usecolormap= <VALUE>,
project_z= <VALUE>,
color= <VALUE>,
start= <VALUE>,
end= <VALUE>,
size= <VALUE>))
# 3次元Surfaceの設定 fig.add_trace(…) | |||
z= ○○○ | z座標のデータ | ||
x= ○○○ | x座標のデータ | ||
y= ○○○ | y座標のデータ | ||
colorscale = ○○○ | カラーバーで使う配色の設定 ‘rainbow’, ‘hot’, ‘ice’などから選択,詳しくはこちら | ||
# 軸の周りの設定 fig.update_scenes(…) | |||
backgroundcolor=○○○ | 背景の色 | ||
gridcolor=○○○ | グリッド線の色 | ||
gridwidth=○○○ | グリッド線の太さ | ||
linecolor=○○○ | 軸線の色 | ||
range=○○○ | 軸の表示範囲 | ||
dtick=○○○ | 軸の目盛り間隔 | ||
mirror=○○○ | ‘True’で反対の軸に設定が反映される | ||
tickfont=dict(…) | color=○○○ | 軸の数値の色 | |
size=○○○ | 軸の数値のサイズ | ||
title=dict(…) | text=○○○ | 軸のラベル名 | |
font=dict(…) | color=○○○ | 軸のラベル名の色 | |
size=○○○ | 軸のラベル名のサイズ | ||
# 軸の周りの設定 fig.update_traces(…) | |||
show=○○○ | “True”, “False”のどちらかを選択 等高線の表示をする /しない を設定できる | ||
usecolormap=○○○ | “True”, “False”のどちらかを選択 等高線の色を3次元surfaceのcolorscaleに合わせる/別に設定する | ||
project_z=○○○ | “True”, “False”のどちらかを選択 z軸平面に等高線を投影する/しない | ||
color=○○○ | 等高線の色の設定(usecolormap= Falseのとき) | ||
start=○○○ | 等高線の表示範囲の始点 | ||
end=○○○ | 等高線の表示範囲の終点 | ||
size=○○○ | 等高線の表示間隔 |
冒頭のグラフのコードはこちら
import plotly.graph_objects as go
import numpy as np
# 関数の定義
def func(x, y):
return np.sin(x) + np.sin(y)
# 関数の値域
x = np.linspace(0, np.pi * 4, 10)
y = np.linspace(0, np.pi * 4, 10)
X, Y = np.meshgrid(x, y)
#作図
fig=go.Figure()
fig.add_trace(go.Surface(z=func(X,Y),
x=x,
y=y,
colorscale='jet'
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(-2,2),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Z',font=dict(color='black',size=18))#family
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='X',font=dict(color='black',size=1))#family
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
gridwidth=2,
linecolor='black',
range=(0,15),
dtick=1,
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='Y',font=dict(color='black',size=18))#family
))
#z軸平面に等高線の併記
fig.update_traces(contours_z=dict(show=True,
usecolormap=True,
project_z=True,
color='gray',
start=-2,
end=2,
size=0.1))
fig.show()
以上,【plotly】もう悩まない!3次元surfaceの作図方法 でした!
コメント