plotlyを使うとグラフをグリグリ動かせるので,普段わかりにくい3次元の散布図であっても直感的に理解しやすくなります。
本記事では,plotlyを使った3次元散布図の作成方法をみていきたいと思います。
カラーバー付きの3次元散布図の作図
目標とするグラフは↓です。
マウスを使ってぐるぐる動かすことができます!
*このグラフのコードは,最後のまとめにあります。一括でコピペしたい場合は,そちらを参考にしてください。
ライブラリ,データの読み込み
データには,scikit-learnのワインのデータセット(公式サイト)を用います。
#ライブラリのインポート
from sklearn import datasets
import pandas as pd
import plotly.graph_objects as go
#ワインデータの読み込み
data = datasets.load_wine()
X=data['data']
Y=data['target']
wine_X = pd.DataFrame(X, columns=data['feature_names'])
df_wine = wine_X.copy()
df_wine['target']=Y
df_wine
df_wineを読み込むと↓のような表が得られます。
df_wineの列の要素は下記の14種類となっています。
- alcohol
- malic_acid
- ash
- alkalinity_of_ash
- magnesium
- total_phenols
- flavonoids
- nonflavanoid_phenols
- proanthocyanins
- color_intensity
- hue
- od280/od315_of_diluted_wines
- proline
- target
このデータセットは3種類のワインの成分を調査した結果になっており,targetの”0”, “1”, “2”で種類分けしてあります。
3次元散布図の作図
3次元散布図の作成をします(公式HPはこちら)。
データは,x軸に”color_intensity”,y軸に”alcohol”,z軸に”alcalinity_of_ash” をプロットします。
*上記は画像です。
コードはこちら↓です。
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=df_wine['color_intensity'],
y=df_wine['alcohol'],
z=df_wine['alcalinity_of_ash'],
mode='markers',
))
fig.show()
いくつか方法はありますが,グラフの作成の大まかな流れとしては,
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次元散布図の作成は,3〜7行目のfig.add_trace(go.Scatter3d(…))で行います。
fig.add_trace(go.Scatter3d(x= <VALUE>,
y= <VALUE>,
z= <VALUE>,
mode= <VALUE>,
))
x= ○○○ | x座標のデータ |
y= ○○○ | y座標のデータ |
z= ○○○ | z座標のデータ |
mode= ○○○ | グラフの描写方法を“markers”, “lines”, “test”から選択 ”markers+lines”のように‘’+”で組み合わせること可能 |
3次元散布図のマーカーの変更,軸ラベル・背景などの設定
このデータセットは3種類のワインの情報があるので,ワインの種類ごとにマーカーのシンボルを変更/軸ラベル・背景の設定してみます。
わかりやすいように予めデータを以下のように分けておきます。
#1種類目のワインのデータ
wine_target0=df_wine[df_wine['target']==0]
#2種類目のワインのデータ
wine_target1=df_wine[df_wine['target']==1]
#3種類目のワインのデータ
wine_target2=df_wine[df_wine['target']==2]
マーカーには,‘circle’,’diamond’,’square’を用いました。
コードはこちらです。
wine_target0=df_wine[df_wine['target']==0]
wine_target1=df_wine[df_wine['target']==1]
wine_target2=df_wine[df_wine['target']==2]
fig = go.Figure()
#wine_target0のグラフ
fig.add_trace(go.Scatter3d(x=wine_target0['color_intensity'],
y=wine_target0['alcohol'],
z=wine_target0['alcalinity_of_ash'],
mode='markers',
name='wine_target0',
marker=dict(color='blue',
size=8,
symbol='circle'),
))
#wine_target1のグラフ
fig.add_trace(go.Scatter3d(x=wine_target1['color_intensity'],
y=wine_target1['alcohol'],
z=wine_target1['alcalinity_of_ash'],
mode='markers',
name='wine_target1',
marker=dict(color='red',
size=8,
symbol='diamond'),
))
#wine_target2のグラフ
fig.add_trace(go.Scatter3d(x=wine_target2['color_intensity'],
y=wine_target2['alcohol'],
z=wine_target2['alcalinity_of_ash'],
mode='markers',
name='wine_target2',
marker=dict(color='lime',
size=8,
symbol='square'),
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcalinity_of_ash',font=dict(color='black',size=10))
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='color_intensity',font=dict(color='black',size=10))
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcohol',font=dict(color='black',size=10))
))
fig.show()
データが3種類となったので,マーカーを変更し判例を追加しました。
マーカーの変更、判例の追加は,fig.add_trace(go.Scatter3d(…))内で設定します。
fig.add_trace(go.Scatter3d(…,
name= <VALUE>,
marker= dict(color= <VALUE>,
size= <VALUE>,
symbol= <VALUE>,
))
name= ○○○ | 判例の名称 | |
marker=dict(…) | color= ○○○ | マーカーの色 |
size= ○○○ | マーカーのサイズ | |
symbol= ○○○ | マーカーの種類を以下から選択 “circle”, “circle-open”, “cross”, “diamond”, “diamond-open”, “square”, “square-open”, “x” |
軸ラベルや背景の設定については,z軸/x軸/y軸それぞれでfig.update_scenes(…)で行っています。
z軸は39-45, x軸は48-54, y軸は57-63行目で設定しており,例えばz軸については
fig.update_scenes(zaxis=dict(backgroundcolor= <VALUE>,
gridcolor= <VALUE>,
linecolor= <VALUE>,
mirror= <VALUE>,
tickfont=dict(color= <VALUE>, size= <VALUE>),
title=dict(text= <VALUE>,
font=dict(color= <VALUE>,size= <VALUE>))
))
zaxis=dict(…) | backgroundcolor= ○○○ | 背景の色 | ||
gridcolor= ○○○ | グリッド線の色 | |||
linecolor= ○○○ | 軸線の色 | |||
mirror= ○○○ | ‘True’で反対の軸に設定が反映される | |||
tickfont=dict(…) | color= ○○○ | 軸の数値の色 | ||
size= ○○○ | 軸の数値のサイズ | |||
title=dict(…) | text= ○○○ | 軸のラベル名 | ||
font=dict(…) | color= ○○○ | 軸のラベル名の色 | ||
size= ○○○ | 軸のラベル名のサイズ |
となっています。
設定項目については,以下の記事でより詳細にまとめているので参考にしてみてください。
symbolの設定
ここではsymbolの設定によるグラフの違いをみてみます。
まずは,”circle-open”, “diamond-open”, “cross”です。
*上記はページの読み込み速度軽減のためpngです。
次は,”square”, “square-open”, “x”です。
*上記はページの読み込み速度軽減のためpngです。
backgroundcolorの設定
backgroundcolorでは,zaxis, xaxis, yaxis,でそれぞれの背景色を設定できます。
それぞれ,backgroundcolor=‘aqua’とするとグラフがどのように変化するかみたいと思います。
カラーバー付き3次元散布図
先ほどの,グラフにカラーバーを追加して”total_phenols”の情報を追加したいと思います。
若干見にくいですが,plotlyはグラフの視点を動かすことができ,判例を押せばそのデータを非表示にできますので情報が多くなっても視覚的に理解しやすいと思います。
コードは以下の通りです。
fig = go.Figure()
#wine_target0のグラフ
fig.add_trace(go.Scatter3d(x=wine_target0['color_intensity'],
y=wine_target0['alcohol'],
z=wine_target0['alcalinity_of_ash'],
mode='markers',
name='wine_target0',
text=wine_target0['total_phenols'],
marker=dict(
symbol='circle',
size=6,
color=wine_target0['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=True)
))
#wine_target1のグラフ
fig.add_trace(go.Scatter3d(x=wine_target1['color_intensity'],
y=wine_target1['alcohol'],
z=wine_target1['alcalinity_of_ash'],
mode='markers',
name='wine_target1',
marker_color=wine_target1['total_phenols'],
text=wine_target1['total_phenols'],
marker=dict(
symbol='diamond',
size=6,
color=wine_target1['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=False)
))
#wine_target2のグラフ
fig.add_trace(go.Scatter3d(x=wine_target2['color_intensity'],
y=wine_target2['alcohol'],
z=wine_target2['alcalinity_of_ash'],
mode='markers',
name='wine_target2',
marker_color=wine_target2['total_phenols'],
text=wine_target2['total_phenols'],
marker=dict(
symbol='square',
size=6,
color=wine_target2['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=False)
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcalinity_of_ash',font=dict(color='black',size=10))
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='color_intensity',font=dict(color='black',size=10))
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcohol',font=dict(color='black',size=10))
))
#判例の位置の設定
fig.update_layout(legend=dict(xanchor='center',
yanchor='bottom',
x=0.85,
y=0.7,
orientation='v',
bgcolor='white',
bordercolor='black',
borderwidth=0.1,
))
fig.show()
まず,カラーバーを表示するために,marker=dict(…)に追記しています(9-18, 28-37, 47-56行目)。
marker=dict(…)に追記した中身は以下の太字になります。
fig.add_trace(go.Scatter3d(…,
marker= dict(…,
colorscale= <VALUE>,
cmin= <VALUE>,
cmax= <VALUE>,
colorbar=dict(title= <VALUE>),
line= dict(color= <VALUE>,width= <VALUE>),
showscale= <VALUE>,
))
marker=dict(…) | colorscale= ○○○ | カラーバーで使う配色の設定 ‘rainbow’, ‘hot’, ‘ice’などから選択,詳しくはこちら | |
cmin= ○○○ | カラーバーの下限値 | ||
cmax= ○○○ | カラーバーの上限値 | ||
colobar=dict(title= ○○○) | カラーバーのタイトル | ||
line=dict(…) | color= ○○○ | マーカーの枠線の色 | |
width= ○○○ | マーカーの枠線の太さ | ||
showscale= ○○○ | ‘True’でカラーバーの表示 |
カラーバーについては以下の記事で詳細にまとめています。よろしければご確認ください。
また,デフォルトのままでは,判例とカラーバーが重なってしまうので87-95行目で判例の位置をfig.update_layout(…)で設定を行います。
fig.update_layout(legend=dict(xanchor= <VALUE>,
yanchor= <VALUE>,
x= <VALUE>,
y= <VALUE>,
orientation= <VALUE>,
bgcolor= <VALUE>,
bordercolor= <VALUE>,
borderwidth= <VALUE>,
))
legend=dict(…) | xanchor= ○○○ | 判例を設置するx座標,y座標について,x方向の始点を決める。 ‘left’, ‘center’, ‘right’から選択 |
yanchor= ○○○ | 判例を設置するx座標,y座標について,y方向の始点を決める。 ‘top, ‘center’, ‘bottom’から選択 | |
x= ○○○ | 判例を設置するx座標 | |
y= ○○○ | 判例を設置するy座標 | |
orientation= ○○○ | ‘h’ : 判例を横方向に並べる ‘v’ : 判例を縦方向に並べる(デフォルト) | |
bgcolor= ○○○ | 判例の背景色 | |
bordercolor= ○○○ | 判例枠の線の色 | |
borderwidth= ○○○ | 判例枠の線の太さ |
判例の位置設定については,2次元グラフのときと同じ設定ですので,以下の記事をご参考ください。
まとめ
3次元散布図の作成方法についてみてきました。
3次元散布図をするためには,
fig.add_trace(go.Scatter3d(x= <VALUE>,
y= <VALUE>,
z= <VALUE>,
mode= <VALUE>,
name= <VALUE>,
# マーカーの設定
marker= dict(color= <VALUE>,
size= <VALUE>,
symbol= <VALUE>,
# カラーバーの設定
colorscale= <VALUE>,
cmin= <VALUE>,
cmax= <VALUE>,
colorbar=dict(title= <VALUE>),
line= dict(color= <VALUE>,width= <VALUE>),
showscale= <VALUE>,
))
x= ○○○ | x座標のデータ | ||
y= ○○○ | y座標のデータ | ||
z= ○○○ | z座標のデータ | ||
mode= ○○○ | グラフの描写方法を“markers”, “lines”, “test”から選択 ”markers+lines”のように‘’+”で組み合わせること可能 | ||
name= ○○○ | 判例の名称 | ||
# マーカーの設定 | |||
marker=dict(…) | color= ○○○ | マーカーの色 | |
size= ○○○ | マーカーのサイズ | ||
symbol= ○○○ | マーカーの種類を以下から選択 “circle”, “circle-open”, “cross”, “diamond”, “diamond-open”, “square”, “square-open”, “x” | ||
# カラーバーの設定 | |||
colorscale= ○○○ | カラーバーで使う配色の設定 ‘rainbow’, ‘hot’, ‘ice’などから選択,詳しくはこちら | ||
cmin= ○○○ | カラーバーの下限値 | ||
cmax= ○○○ | カラーバーの上限値 | ||
colobar=dict(title= ○○○) | カラーバーのタイトル | ||
line=dict(…) | color= ○○○ | マーカーの枠線の色 | |
width= ○○○ | マーカーの枠線の太さ | ||
showscale= ○○○ | ‘True’でカラーバーの表示 |
で設定します。
軸ラベルについては以下をご確認ください。
fig.update_scenes(zaxis=dict(backgroundcolor= <VALUE>,
gridcolor= <VALUE>,
linecolor= <VALUE>,
mirror= <VALUE>,
tickfont=dict(color= <VALUE>, size= <VALUE>),
title=dict(text= <VALUE>,
font=dict(color= <VALUE>,size= <VALUE>))
))
zaxis=dict(…) | backgroundcolor= ○○○ | 背景の色 | ||
gridcolor= ○○○ | グリッド線の色 | |||
linecolor= ○○○ | 軸線の色 | |||
mirror= ○○○ | ‘True’で反対の軸に設定が反映される | |||
tickfont=dict(…) | color= ○○○ | 軸の数値の色 | ||
size= ○○○ | 軸の数値のサイズ | |||
title=dict(…) | text= ○○○ | 軸のラベル名 | ||
font=dict(…) | color= ○○○ | 軸のラベル名の色 | ||
size= ○○○ | 軸のラベル名のサイズ |
冒頭のグラフのコードはこちら
#ライブラリのインポート
from sklearn import datasets
import pandas as pd
import plotly.graph_objects as go
#ワインデータの読み込み
data = datasets.load_wine()
X=data['data']
Y=data['target']
wine_X = pd.DataFrame(X, columns=data['feature_names'])
df_wine = wine_X.copy()
df_wine['target']=Y
df_wine
#データの分割
wine_target0=df_wine[df_wine['target']==0]
wine_target1=df_wine[df_wine['target']==1]
wine_target2=df_wine[df_wine['target']==2]
fig = go.Figure()
#wine_target0のグラフ
fig.add_trace(go.Scatter3d(x=wine_target0['color_intensity'],
y=wine_target0['alcohol'],
z=wine_target0['alcalinity_of_ash'],
mode='markers',
name='wine_target0',
text=wine_target0['total_phenols'],
marker=dict(
symbol='circle',
size=6,
color=wine_target0['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=True)
))
#wine_target1のグラフ
fig.add_trace(go.Scatter3d(x=wine_target1['color_intensity'],
y=wine_target1['alcohol'],
z=wine_target1['alcalinity_of_ash'],
mode='markers',
name='wine_target1',
marker_color=wine_target1['total_phenols'],
text=wine_target1['total_phenols'],
marker=dict(
symbol='diamond',
size=6,
color=wine_target1['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=False)
))
#wine_target2のグラフ
fig.add_trace(go.Scatter3d(x=wine_target2['color_intensity'],
y=wine_target2['alcohol'],
z=wine_target2['alcalinity_of_ash'],
mode='markers',
name='wine_target2',
marker_color=wine_target2['total_phenols'],
text=wine_target2['total_phenols'],
marker=dict(
symbol='square',
size=6,
color=wine_target2['total_phenols'],
colorscale="rainbow",
cmin=0.5,
cmax=4,
colorbar=dict(title='total_phenols'),
line=dict(color='black', width=0.5),
showscale=False)
))
#z軸の軸,背景の設定
fig.update_scenes(zaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcalinity_of_ash',font=dict(color='black',size=10))
))
#x軸の軸,背景の設定
fig.update_scenes(xaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='color_intensity',font=dict(color='black',size=10))
))
#y軸の軸,背景の設定
fig.update_scenes(yaxis=dict(backgroundcolor='white',
gridcolor='black',
linecolor='black',
mirror=True,
tickfont=dict(color='black', size=12),
title=dict(text='alcohol',font=dict(color='black',size=10))
))
#判例の位置の設定
fig.update_layout(legend=dict(xanchor='center',
yanchor='bottom',
x=0.85,
y=0.7,
orientation='v',
bgcolor='white',
bordercolor='black',
borderwidth=0.1,
))
fig.show()
以上,【plotly】ぐるぐる動かす!3次元散布図の作図方法でした!
コメント