こんな人にオススメ
plotlyのScatter
のマーカーの大きさとか線の太さが、実際にはどれくらいなのかがわかりやすいようなグラフを作りたい。
ということで、今回はplotly
の散布図で使われるmarker
サイズやline
の太さがどれくらいなのかが一目でわかる、一覧グラフを作成する。毎回サイズを1ずつ変更していい感じにするのが面倒。だったら予め一覧を作成しておいて、それを参考にしたらいい。
今回は設定した大きさ・太さ一覧を全てプロットするグラフとスライダー機能を使って手動で一覧を変更することができるグラフの2種類を作成する。
また、go
の散布図go.Scatter
を使って一覧を作成するけど、px
にも応用できる。go
とpx
の散布図については以下参照。
続きを見る 続きを見る
【plotly&go.Scatter】plotlyの散布図グラフの描き方
【plotly&px.scatter】pxでの散布図の描き方
python環境は以下。
- Python 3.10.1
- plotly 5.4.0
- plotly-orca 3.4.2
作成したコード全文
マーカーのサイズを変更(一覧表示)
まずはマーカーサイズを変更したグラフから。symbol
は以下の7種類を使用、マーカーのサイズは0から30までとした。ただし、0にするとデフォルトの6と同じサイズになることに注意。
circle
: 円形square
: 正方形diamond
: ダイヤモンド(菱形)cross
: 十字x
: バツtriangle-up
: 上向きの三角形star
: 星
プロットの方法は、まずマーカーサイズsize
を固定してfor
ループ。その中でマーカーシンボルsymbol
を指定してforループを回して、size
・symbol
を指定した状態でgo.Scatter
で散布図を作成している。
そのまま散布図を作成すると凡例の数が全プロット分できてしまうので、一旦showlegend=False
で凡例の表示をオフに。その後、最後のプロットの凡例だけをオンにしている。
また、各シンボルで一括りのグラフにするためlegendgroup
をシンボル名に設定。これで凡例をクリックしたときの表示・非表示がシンボルごとになる。
レイアウトに関しては横軸をシンボル名に変更するためにtickmode
, ticktext
, tickvals
を指定。縦軸はtitle
で軸ラベルを指定した。また、凡例はデフォルトでは右上だが、今回は左下に変更。
import plotly.graph_objects as go import plotly.io as pio # マーカーのサイズを変更 # マーカーのサイズ sizes = range(31) # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) length = len(symbols) # シンボルの数 plot = [] for y, size in enumerate(sizes): for num, symbol in enumerate(symbols): d = go.Scatter( x=(num,), y=(y,), name=f"{symbol}", marker=dict(size=size, symbol=symbol), # マーカーのサイズとシンボル showlegend=False, # 一旦全てのプロットの凡例を非表示に legendgroup=symbol # 同じシンボルは同じ凡例のグループに入れる ) plot.append(d) # 最後のプロットの凡例だけ表示するように変更 for num, _ in enumerate(symbols): plot[-1 - num]['showlegend'] = True layout = go.Layout( height=1000, # グラフの高さを高く変更 xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=symbols, tickvals=list(range(length)) ), # 縦軸の範囲指定と軸ラベル作成 yaxis=dict(range=(-1, max(sizes) + 1), title='marker size'), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'marker_size_list' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
マーカーの枠線の太さを変更(一覧表示)
続いてはマーカーの枠線の太さを変更。変更するのは0から11。大きくしすぎるとマーカー自体のサイズよりも枠線の方が大きくなってしまうからちょうど良さげな値にした。
基本的にはマーカーサイズと同じコードとなる。異なる点は、引数marker
の中の引数line
を設定する点。今回は枠線の太さなので引数width
を指定した。
また、枠線の色はデフォルトでは黒っぽい色だが、変更したい場合は引数line
の中の引数color
で好きな色を指定したらいい。
import plotly.graph_objects as go import plotly.io as pio # マーカーの枠線の太さ widths = range(11) # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) length = len(symbols) # シンボルの数 plot = [] for y, width in enumerate(widths): for num, symbol in enumerate(symbols): d = go.Scatter( x=(num,), y=(y,), name=f"{symbol}", marker=dict( symbol=symbol, size=20, # マーカーのサイズを大きめに line=dict(width=width,), # 枠線の太さ ), showlegend=False, # 一旦全てのプロットの凡例を非表示に legendgroup=symbol # 同じシンボルは同じ凡例のグループに入れる ) plot.append(d) # 最後のプロットの凡例だけ表示するように変更 for num, _ in enumerate(symbols): plot[-1 - num]['showlegend'] = True layout = go.Layout( height=1000, # グラフの高さを高く変更 xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=symbols, tickvals=list(range(length)) ), # 縦軸の範囲指定と軸ラベル作成 yaxis=dict(range=(-1, max(widths) + 1), title='marker line width'), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'marker_linewidth_list' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
ラインプロットの線の太さを変更(一覧表示)
続いては線のプロットをした時の線の太さを変更。上のグラフの線の太さが大きい部分だと、もはやプロットする幅が足りなくて波線とかが成り立たなくなっている。
これはさっきのマーカーとは異なって線のプロットとなるので1点だけという指定ができない。今回は左右と中心の合計3点を結んでプロットした。
点だけのプロットの場合はgo.Scatter
の引数mode
はデフォルトの’marker’
でいいけど、線のプロットの場合はmode=’lines’
にする必要がある。あとは大体さっきと同じ。
import plotly.graph_objects as go import plotly.io as pio # 線の太さ widths = range(31) # 線種 dashs = ( 'solid', # 実線 'dot', # 点線 'dash', # 破線 'longdash', # 長めの破線 'dashdot', # 一点鎖線 'longdashdot', # 長めの一点鎖線 '5px,10px,2px,2px' # 5, 10, 2, 2 pixで線を描画 ) length = len(dashs) # 線種の数 plot = [] for y, width in enumerate(widths): for x, dash in enumerate(dashs): d = go.Scatter( x=(x - 0.4, x, x + 0.4), y=(y, y, y), name=f"{dash}", mode='lines', line=dict(dash=dash, width=width), showlegend=False, # 一旦全てのプロットの凡例を非表示に legendgroup=dash # 同じシンボルは同じ凡例のグループに入れる ) plot.append(d) # 最後のプロットの凡例だけ表示するように変更 for num, _ in enumerate(dashs): plot[-1 - num]['showlegend'] = True layout = go.Layout( height=1000, # グラフの高さを高く変更 xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=dashs, tickvals=list(range(length)) ), yaxis=dict(range=(-1, max(widths) + 1), title='line width'), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), ) # グラフを表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'line_width_list' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
マーカー・線の不透明度を変更(一覧表示)
最後はプロットの不透明度opacity
を変更したグラフ。不透明度とは0から1の範囲でプロットの色の濃さを示すもの。1だとクッキリハッキリ見える一方で、0に近づくにつれて透明になっていく。
今回はmode=’lines+markers’
で線とマーカーの同時使いをした。また、symbol
もdash
も使用して、先程までのグラフの組み合わせもしておいた。
残りの部分はさっきと同じ感じだけど、さっきの1プロットは左右+中心。しかし、こうすると中心部分のプロットがマーカーとなってごちゃついたので、ここでは左右だけにした。
import plotly.graph_objects as go import plotly.io as pio # 不透明度 opacities = [i / 10 for i in range(11)] # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) dashs = ( 'solid', # 実線 'dot', # 点線 'dash', # 破線 'longdash', # 長めの破線 'dashdot', # 一点鎖線 'longdashdot', # 長めの一点鎖線 '5px,10px,2px,2px' # 5, 10, 2, 2 pixで線を描画 ) length = len(symbols) # シンボル(ダッシュ)要素数 plot = [] for y, opacity in enumerate(opacities): for x, (symbol, dash) in enumerate(zip(symbols, dashs)): d = go.Scatter( x=(x - 0.25, x + 0.25), y=(y / 10, y / 10), name=f"{symbol} と {dash}", mode='lines+markers', # ラインとマーカーを同時に描画 marker=dict(symbol=symbol, size=20), line=dict(dash=dash, width=3), opacity=opacity, # 不透明度を変更 showlegend=False, # 一旦全てのプロットの凡例を非表示に # 同じシンボルと線種の組み合わせは同じ凡例のグループに入れる; legendgroup=f"{symbol} と {dash}" ) plot.append(d) # 最後のプロットの凡例だけ表示するように変更 for num, _ in enumerate(dashs): plot[-1 - num]['showlegend'] = True # 横軸用の文字列作成 ticktexts = [] for symbol, dash in zip(symbols, dashs): ticktext = f"{symbol}<br>{dash}" ticktexts.append(ticktext) print(ticktexts) # ['circle<br>solid', 'square<br>dot', 'diamond<br>dash', 'cross<br>longdash', 'x<br>dashdot', 'triangle-up<br>longdashdot', 'star<br>5px,10px,2px,2px'] layout = go.Layout( height=1000, # グラフの高さを高く変更 xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=dashs, tickvals=list(range(length)) ), yaxis=dict(range=(-1, len(opacities)), title='line width'), # 凡例はグラフ下部に横向きで(yの位置は記事掲載時のいい感じの値にしている) legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show()
マーカーのサイズを変更(スライダー表示)
続いては先程のマーカーサイズ一覧をplotly
のスライダーを使用して作成してみる。スライダー機能については以下参照。
続きを見る 続きを見る
【plotly&スライダー】plotlyのslidersにスライダーを追加
【plotly&ボタンとスライダー】goとpxでのupdatemenusとsliders
大枠は一覧作成と同じだけど、以下の点が異なる。
- 凡例グループ
legendgroup
の設定を表示・非表示visible
の設定に変更 - 初期表示をデフォルトの値に該当するplotに設定
- スライダーで各サイズに該当するplotのみを表示して、それ以外を非表示に
- go.Layoutにスライダー情報slidersを設定
スライダー機能でプロットの切り替えをするってのは、各スライダーに該当するプロットだけを表示することに等しい。ここでは一旦全てのプロットのvisibleをFalse
、非表示にしてから該当するプロットだけをvisible=True
で表示するようにしている。
なお、for
ループはマーカーサイズを初めに持ってきているので、visible
をTrue
にするときはvisible[size * length: (size + 1) * length]
で各サイズ x シンボルの数ごとに設定する必要がある。
もちろん一括で= [True] * length
とせずに1プロットずつTrue
に変更してもいい。
import plotly.graph_objects as go import plotly.io as pio # マーカーのサイズ sizes = range(31) # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) length = len(symbols) # シンボルの数 plot = [] for size in sizes: for x, symbol in enumerate(symbols): d = go.Scatter( x=(x,), y=(0,), name=f"{symbol}", marker=dict(size=size, symbol=symbol), visible=False # 一旦全てのプロットを非表示に ) plot.append(d) # 初期表示のプロットだけ表示するように変更 default = 6 # symbol sizeのデフォルト値 for num, _ in enumerate(symbols): plot[default * length + num]['visible'] = True steps = [] for size in sizes: # 一旦すべてのプロットを非表示に visible = [False] * len(plot) # 各マーカーサイズのスライダーに該当するプロットだけ表示に変更 visible[size * length: (size + 1) * length] = [True] * length step = dict( method='update', label=size, args=[ dict(visible=visible), # 表示・非表示の設定 dict(title=f"marker size = {size}",) # 各スライダーのグラフタイトル ], ) steps.append(step) # レイアウトにスライダーを設置 sliders = [ dict( active=default, steps=steps, currentvalue=dict(prefix='size='), # スライダーの上の現在値部分の接頭辞 ) ] layout = go.Layout( xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=symbols, tickvals=list(range(length)) ), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), sliders=sliders, # スライダー情報 ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'marker_size_slider' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
マーカーの枠線の太さを変更(スライダー表示)
マーカーの枠線の太さの変更も、サイズ変更と同じようにスライダー化することが可能。サイズ変更が単に枠線の太さ変更になっただけ。
枠線の太さのデフォルト値は1なので、変数default
とスライダーsliders
の引数active
を1に。これで初期表示を枠線の太さ=1の状態にできる。
import plotly.graph_objects as go import plotly.io as pio # マーカーの枠線の太さ widths = range(10) # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) length = len(symbols) # シンボルの数 plot = [] for width in widths: for x, symbol in enumerate(symbols): d = go.Scatter( x=(x,), y=(0,), name=f"{symbol}", marker=dict( symbol=symbol, opacity=0.5, # マーカーをちょっと透明に size=50, # マーカーのサイズを大きめに line=dict(width=width,), ), visible=False # 一旦全てのプロットを非表示に ) plot.append(d) # 初期表示のプロットだけ表示するように変更 default = 1 # symbol line widthのデフォルト値はないからとりあえず1に for num, _ in enumerate(symbols): plot[default * length + num]['visible'] = True steps = [] for width in widths: # 一旦すべてのプロットを非表示に visible = [False] * len(plot) # 各マーカーの枠線太さのスライダーに該当するプロットだけ表示に変更 visible[width * length: (width + 1) * length] = [True] * length step = dict( method='update', label=width, args=[ dict(visible=visible), # 表示・非表示の設定 # 各スライダーのグラフタイトル dict(title=f"marker line width = {width}",) ], ) steps.append(step) # レイアウトにスライダーを設置 sliders = [ dict( active=default, steps=steps, currentvalue=dict(prefix='width='), # スライダーの上の現在値部分の接頭辞 ) ] layout = go.Layout( xaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名に変更 tickmode='array', ticktext=symbols, tickvals=list(range(length)) ), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=0, yanchor='bottom', orientation='h'), sliders=sliders, # スライダー情報 ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'marker_linewidth_slider' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
ラインプロットの線の太さを変更(スライダー表示)
ラインプロットの線の太さ変更も同じようにスライダーで描ける。ただ、一覧表示の時よりも使う面積が小さいので縦軸にdash
を持ってくるスタイルに変更。
こうすることで、横長のグラフと太くなった線の兼ね合いがうまくいってキレイに見えるようになる。
import plotly.graph_objects as go import plotly.io as pio # 線の太さ widths = range(31) # 線種 dashs = ( 'solid', # 実線 'dot', # 点線 'dash', # 破線 'longdash', # 長めの破線 'dashdot', # 一点鎖線 'longdashdot', # 長めの一点鎖線 '5px,10px,2px,2px' # 5, 10, 2, 2 pixで線を描画 ) length = len(dashs) # 線種の数 plot = [] for width in widths: for y, dash in enumerate(dashs): d = go.Scatter( x=(0, 1), y=(y, y), name=f"{dash}", mode='lines', line=dict(dash=dash, width=width), visible=False # 一旦全てのプロットを非表示に ) plot.append(d) # 初期表示のプロットだけ表示するように変更 default = 2 # line widthのデフォルト値 for num, _ in enumerate(dashs): plot[default * length + num]['visible'] = True steps = [] for width in widths: # 一旦すべてのプロットを非表示に visible = [False] * len(plot) # 各線の太さのスライダーに該当するプロットだけ表示に変更 visible[width * length: (width + 1) * length] = [True] * length step = dict( method='update', label=width, args=[ dict(visible=visible), # 表示・非表示の設定 dict(title=f"line width = {width}",) # 各スライダーのグラフタイトル ], ) steps.append(step) # レイアウトにスライダーを設置 sliders = [ dict( active=default, steps=steps, currentvalue=dict(prefix='width='), # スライダーの上の現在値部分の接頭辞 ) ] layout = go.Layout( height=1000, yaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をダッシュ名に変更 tickmode='array', ticktext=dashs, tickvals=list(range(length)) ), # 凡例はグラフ下部に横向きで legend=dict(x=0, y=-0.3, yanchor='bottom', orientation='h'), sliders=sliders, # スライダー情報 ) # グラフを表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'line_width_slider' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
マーカー・線の不透明度を変更(スライダー表示)
最後は不透明度の変更。こちらもプロットで使う面積が小さくなるので一覧表示とは表示の仕方を変更している。
マーカーについては両橋の2点だけだと寂しかったので、間にも追加して合計6点とした。
import plotly.graph_objects as go import plotly.io as pio # マーカーと線の透明度を変更 # 不透明度 opacities = [i / 10 for i in range(11)] # シンボルの種類 symbols = ( 'circle', # 円形 'square', # 正方形 'diamond', # ダイヤモンド(菱形) 'cross', # 十字 'x', # バツ 'triangle-up', # 上向きの三角形 'star' # 星 ) dashs = ( 'solid', # 実線 'dot', # 点線 'dash', # 破線 'longdash', # 長めの破線 'dashdot', # 一点鎖線 'longdashdot', # 長めの一点鎖線 '5px,10px,2px,2px' # 5, 10, 2, 2 pixで線を描画 ) length = len(symbols) # シンボル(ダッシュ)要素数 plot = [] for opacity in opacities: for x, (symbol, dash) in enumerate(zip(symbols, dashs)): d = go.Scatter( x=(0, 0.2, 0.4, 0.6, 0.8, 1), y=(x, x, x, x, x, x), name=f"{symbol} と {dash}", mode='lines+markers', # ラインとマーカーを同時に描画 marker=dict(symbol=symbol, size=20), line=dict(dash=dash, width=3), opacity=opacity, # 不透明どを変更 visible=False # 一旦全てのプロットを非表示に ) plot.append(d) # 初期表示のプロットだけ表示するように変更 # 適当にopacity=0.2に設定 for num, _ in enumerate(symbols): plot[2 * length + num]['visible'] = True steps = [] for num, opacity in enumerate(opacities): # 一旦すべてのプロットを非表示に visible = [False] * len(plot) # 各マーカーサイズのスライダーに該当するプロットだけ表示に変更 visible[num * length: (num + 1) * length] = [True] * length step = dict( method='update', label=opacity, args=[ dict(visible=visible), # 表示・非表示の設定 dict(title=f"opacity = {opacity}",) # 各スライダーのグラフタイトル ], ) steps.append(step) # レイアウトにスライダーを設置 sliders = [ dict( active=2, steps=steps, currentvalue=dict(prefix='opacity='), # スライダーの上の現在値部分の接頭辞 ) ] # 横軸用の文字列作成 ticktexts = [] for symbol, dash in zip(symbols, dashs): ticktext = f"{symbol}<br>{dash}" ticktexts.append(ticktext) print(ticktexts) # ['circle<br>solid', 'square<br>dot', 'diamond<br>dash', 'cross<br>longdash', 'x<br>dashdot', 'triangle-up<br>longdashdot', 'star<br>5px,10px,2px,2px'] layout = go.Layout( height=1000, yaxis=dict( range=(-1, length), # 横軸の範囲を固定 # 横軸の目盛表記をシンボル名とダッシュ名に変更(brやぐで改行している) tickmode='array', ticktext=ticktexts, tickvals=list(range(length)) ), # 凡例はグラフ下部に横向きで(yの位置は記事掲載時のいい感じの値にしている) legend=dict(x=0, y=-0.3, yanchor='bottom', orientation='h'), sliders=sliders, # スライダー情報 ) # グラフの表示 fig = go.Figure(data=plot, layout=layout) fig.show() # グラフ保存 save_name = 'opacity_slider' pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html") pio.write_image(fig, f"{save_name}.png")
一覧があると確認し放題
ということで、今回はplotly
のマーカーのサイズや線の太さ一覧グラフを作成した。これで下手に値で悩む必要が減るだろう。
matplotlib
, plt
だとメジャーなのでいろんなサイトで今回のようなグラフがあるけど、plotly
はまだまだマイナーなのか、そんなサイトが少ないか無い。
本記事を参考にして、各人のグラフをより効率的に作成していただければ幸いだ。
関連記事
-
-
【plotly&fig作成と更新】add_traceやupdate_layoutの使い方
2022/8/19
こんな人にオススメ plotlyでグラフを& ...
-
-
【plotly&size, width】Scatterのサイズやlineの太さ一覧表を作成
2022/8/19
こんな人にオススメ plotlyのScatterのマー ...
-
-
【plotly&legendまとめ】凡例の引数一覧
2022/8/19
こんな人にオススメ plotlyのlayoutの引数leg ...
-
-
【plotly&pattern】棒グラフとかのパターンまとめ
2022/8/19
こんな人にオススメ plotlyの棒グラフ& ...