こんな人にオススメ
plotly
っていじれる項目が多くて設定が面倒。何かいいテンプレートとかって作ってませんかね?
ということで、今回はplotly
でグラフを描画する際のテンプレートを列挙する。本記事は、自分用の備忘録としての役割も果たしているので、文章量が少なめ。コード閲覧・確認・コピー用。
python環境は以下。
- Python 3.9.4
- numpy 1.20.3
- plotly 4.14.3
なお、ここに書かれた内容は執筆者のPC内で「plotly_layout_template.py
」というファイルに書かれており、他のpy
ファイルでplotly
のグラフを作成する際に読み込まれる。
その際にはディレクトリが「plotly_layout_template.py
」方が2階層上なので、それぞれのグラフの方には読み込みディレクトリとして../../
が書かれる。イメージは以下。
. └── plotly_layout_template.py ├── folder1 │ └── plotly1.py └── folder2 └── plotly2.py
layout
テンプレート
plotly
のレイアウトはgo.Layout
で行う。dict
形式で各項目と副項目を設定する。
[box class="box27" title="2021年6月27日追記"]テンプレート内にhoverlabel
を入れれば、毎回Scatter
の部分でhoverlabel
を設定しなくてもいい![/st-mybox]
def plotly_layout(): """plotlyのlayoutのtemplate Returns ------- dict plotlyのlayoutのtemplate 各グラフのlayout作成時に上書きすることも可能 """ layout_template = dict( layout=go.Layout( title=dict( x=0., y=0.99, xanchor='left', yanchor='top', xref='paper', yref='container', ), xaxis=dict( ticks='inside', zeroline=False, linewidth=1, showline=True, linecolor='black', mirror='allticks', ), yaxis=dict( ticks='inside', zeroline=False, linewidth=1, showline=True, linecolor='black', mirror='allticks', ), yaxis2=dict( gridcolor='#d5d5d5', ticks='inside', zeroline=False, linewidth=1, showline=True, linecolor='black', mirror=False, overlaying='y', side='right', ), font=dict(family='Times New Roman', color='black', size=20), paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)', legend=dict( x=1, y=1, orientation='v', xanchor='right', yanchor='top', itemclick='toggleothers', itemdoubleclick='toggle', bgcolor='rgba(0,0,0,0)', bordercolor='black', borderwidth=1, ), margin=dict(l=50), hoverdistance=30, showlegend=True, hovermode='closest', # この部分を追記するとScatterで毎回指定しなくてもいい! hoverlabel=dict(font=dict(family='Times New Roman', size=30)), ) ) return layout_template
config
config
はplotly
のグラフの右上の方に表示される、グラフの拡大・縮小や追加で図形の描画などを決めるボタン。
[box class="box27" title="2021年7月11日追記"]軸ラベルとかを自由に変更できるか否かを決める引数tfのデフォルト値をFalse
に設定[/st-mybox]
[box class="box27" title="2021年8月9日追記"]plotly
のv5以降では、デフォルトでtoggleSpikeLines
などが非表示なるようなので明示[/st-mybox]
def plotly_config(tf=False): """plotlyのconfigの設定一覧 Parameters ---------- tf : bool 軸ラベルや凡例の位置を編集可能にするか否か, by default False Returns ------- dict 設定したplotlyのconfig """ config = { # プロット領域上でスクロールするとズームイン、ズームアウトが可能 'scrollZoom': True, # タイトルとかの編集可能 'editable': tf, # ダブルクリックの許容時間/ms 'doubleClickDelay': 1000, # お絵描きツール追加 'modeBarButtonsToAdd': [ 'drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape', 'togglehover', 'togglespikelines', 'hoverclosest', 'hovercompare', 'v1hovermode', ], # ディスプレイにconfigのメニューバーを常に表示する 'displayModeBar': True, # 一部編集可能に 'edits': { 'legendText': True, 'titleText': True, 'axisTitleText': True, 'annotationText': True, }, # # デフォルトで表示されているconfigを消したい時 # 'modeBarButtonsToRemove': [ # 'toImage', # 'zoom2d', # 'pan2d', # 'select2d', # 'lasso2d', # 'zoomIn2d', # 'zoomOut2d', # 'autoScale2d', # 'resetScale2d', # 'toggleSpikelines', # 'hoverClosestCartesian', # 'hoverCompareCartesian', # ], # # plotlyのロゴを消したい時 # 'displaylogo': False, } return config
プロット作成
プロット点の作成。今回は以下の式のa
の値を0
から4
まで変化させたデータをfor
で回しながら使用した。
$$y\ =\ ax$$
レイアウトについてはgo.Layout
の引数template
に、config
についてはグラフ描画時のplotly.offline.iplot
の引数config
に入れて使用。
HTMLでのグラフ保存時にconfig
を効かせるかどうかも指定でき、今回はconfig
を効かせておいた。本記事のグラフもconfig
が効いているのでぜひいじってみてほしい。
[box class="box27" title="2021年6月27日追記"]テンプレート内にhoverlabel
を入れているので、Scatter
の部分でhoverlabel
を設定しなくてもいい![/st-mybox]
def graph(): """レイアウト、configのテンプレートを読み込んだ plotlyのグラフを作成してみる """ x = np.arange(10) y = x colors = ('red', 'blue', 'green', 'black', 'deeppink') # プロットするデータを配列に入れる plot = [] for num, color in enumerate(colors): name = f"y={num}x" d = go.Scatter( mode='lines+markers', x=x, y=y * num, name=name, marker=dict(symbol='circle'), line=dict(dash='solid', color=color), # hoverlabel=dict( # font=dict( # family='Times New Roman', size=40 # ) # ), hovertemplate=f"{name}<br>" + 'x=%{x} <br>' + 'y=%{y} <br>' + "<extra></extra>", ) plot.append(d) # レイアウトを決める layout = go.Layout( template=plotly_layout(), title=dict( text='title', ), xaxis=dict( title='x', ), yaxis=dict( title='y', ), legend=dict( xanchor='right', ) ) # 作成したデータの入った配列と、レイアウトの配列を図にする fig = go.Figure(data=plot, layout=layout) plotly.offline.iplot(fig, config=plotly_config(tf=True),) # 作成したグラフを保存 pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' # ファイル保存 pio.write_html( fig, 'test_plotly.html', auto_open=False, config=plotly_config(tf=False), ) pio.write_image(fig, 'test_plotly.png') graph()
グラフ描画
以上の設定を行なって実際に作成したグラフが上。実際にHTML表記にしたのが以下のグラフだ。
プログラムを1つにして表示
layout
、config
、plot
を一つにしたコードを示す。以下をコピペすればとりあえずはグラフができる(モジュールとかが揃っていれば)。
保守性を高めるために
今回はひたすらplotly
の設定についての記事だった。この記事に書いているテンプレート(layout
, config
)を予めどこかに設定し、毎回読み込むことで毎回同じクオリティのグラフが出来上がる。
毎回ファイルに上記のテンプレートを書き込むことは大変なのは目に見えているが、何よりも大切なのが「保守性」。
これは機能の拡張のしやすさとか修理のしやすさとかを表す言葉で、もし、テンプレートの一部を変更するとなると、毎回ファイルのにテンプレートを書いている場合は全てのファイルで変更を加えないといけない。
しかし、今回のように予めテンプレートとして他の場所に置いておけば、このファイルだけ変更すれば事足りる。すると
- 変更忘れ
- 変更ミス
- 無駄な変更時間
が無くなってWinWIn。これからプログラミングを学ぶ人はこういう点も頭に入れておいていただければ幸いだ。執筆者自身まだまだ保守性の向上の余地ありなので共に成長しましょう。
研究でのpythonプログラム。
プログラムの保守性が低くてストレス。これまでとは異なるデータ使用時、これまでのコードではうまい具合に出力できない問題。
一応正常に動くが、誤解を生むような出力がある。
なるべく未来を見据え、機能拡張は意識して達成できているが、まだ詰めが甘い。#保守性
— メガネ🦊【ブログ工事中】ガジェットとPythonのブロガー (@m_ten_pa) June 6, 2021
関連記事
-
-
【plotlyテンプレート】plotlyのグラフ作成テンプレート
続きを見る
-
-
【plotly&go.Scatter】plotlyの散布図グラフの描き方
続きを見る
-
-
【plotly&マーカー】plotlyのマーカーのシンボル
続きを見る
-
-
【plotly&config】グラフのツールバーを編集する
続きを見る
-
-
【plotly&orca】plotlyで静止画保存(orca)
続きを見る
-
-
【plotly&バブルチャート】plotlyで各国の収入と平均寿命の時代変化をバブルチャートで描く
続きを見る
-
-
【Automator活用術】Macで生産性を上げる作業の自動化術
続きを見る
-
-
【Mac&タイピング】タッチタイピングで分間300打を超える方法
続きを見る
-
-
【python&独学】独学である程度pythonを習得するマインド
続きを見る
-
-
【python&初級】のlistとかforとかifとかまとめ
続きを見る