plotly入門

Python Plotly入門⑥ - 棒グラフ(Bar Chart)

2021年6月17日

今回はPlotlyを使った棒グラフの作成をしたいと思います。

棒グラフも非常によく使うグラフの一つですね。

以下のようなグラフを作成します。

公式HPの解説はこちらです。

Plotly Expressを使った棒グラフの作成

Plotly Expressを使うと、Pandasのデータフレームを使って簡単に作成することが可能です。

以下のような月ごとの株価リターンのデータがあるとします(df_meanという変数名にします)。

month	スノーピーク	  ANA	    ぐるなび
1	-0.003291	-0.003139	-0.004263
2	-0.021542	-0.008886	-0.011221
3	0.002966	-0.002391	-0.011262
4	0.005282	-0.005839	0.002946
5	0.014990	0.007604	0.008425
6	0.004855	-0.002305	0.005820
7	0.001204	-0.005411	-0.022005
8	0.015636	0.010286	0.018797
9	0.010066	-0.004093	0.005788
10	0.000655	-0.003011	-0.005842
11	-0.007714	0.006519	-0.008765
12	0.008848	-0.004136	0.000687

まず、plotly.expressをインポートします。

import plotly.express as px

一つのデータを表示するだけであれば以下のような2行だけで作成可能です。

fig = px.bar(df_mean, x='month', y='スノーピーク')
fig.show()

もしくは以下の1行だけでも可能です。

px.bar(df_mean, x='month', y='スノーピーク')

第一引数はデータフレーム、xはx軸に指定したい列、yはy軸に指定したい列を設定します。

次に複数のデータを一つのグラフに表示する場合です。

この場合は以下のようなデータフレームになっている必要があります。

name	       month	  price
ANA	         1	-0.003139
ANA	         2	-0.008886
ANA	         3	-0.002391
ANA	         4	-0.005839
...	        ...  	   ...
ぐるなび	         1	-0.004263
ぐるなび	         2	-0.011221
ぐるなび	         3	-0.011262
ぐるなび	         4	 0.002946
...	        ...	   ...
スノーピーク	 1	-0.003291
スノーピーク	 2	-0.021542
スノーピーク	 3	 0.002966
スノーピーク	 4	 0.005282
...	        ...	   ...

そして、以下のコードを実行します。

fig = px.bar(df_vertical_mean, x='month', y='price', 
             color='name', barmode='group')

すべてのリターンが"return"という列に入っているので、colorという引数に"name"を指定することで、name列で銘柄ごとに分けています。

また、barmode='group'とすることで、棒を横に並べています。

このデータに対しては適当ではありませんが、barmodeをデフォルトの"relative"にすると積み上げ式になります。

barmodeを"overlay"にすると重なり合った棒グラフになります。

どれを選ぶかは分析の内容次第になりますので、目的に合ったグラフを選んでください。

それ以外のよく使うプロパティとして、以下のようなものがあります。

  • color
    バーの色を変える。
  • width
    バーの幅を変える。
  • title
    グラフのタイトルを設定する。
  • hover_data
    カーソルを当てたときの表示を変える。

他の設定も知りたい方は以下をご参照ください。

https://plotly.com/python-api-reference/generated/plotly.express.bar

plotly.graph_objectsを使ったグラフ作成

では、plotly.expressではなく、よりきめ細やかな設定のできるplotly.graph_objectsを使った棒グラフの作成方法を見ていきましょう。

plotly.expressは非常にシンプルですが、plotly.graph_objectsもそれほど大変なわけではないので、個人的にはこちらをオススメします。

まず、plotly.graph_objectsをインポートします。

import plotly.graph_objects as go

あとはスノーピーク、ANA、ぐるなびの3つのデータを表示させたいので、それぞれのデータをgo.Bar()で作成し、リストにしてgo.Figure()に渡します。

data1 = go.Bar(x=df_mean['month'],
               y=df_mean['スノーピーク'],
               name='スノーピーク')
data2 = go.Bar(x=df_mean['month'],
               y=df_mean['ANA'],
               name='ANA')
data3 = go.Bar(x=df_mean['month'],
               y=df_mean['ぐるなび'],
               name='ぐるなび')
go.Figure([data1, data2, data3]).show()

もしくは、go.Figure()のadd_traceでデータを順番に追加する方法です。

どちらでも同じですので、使いやすい方を使えば良いと思います(私は最近こちらを使っています)。

fig = go.Figure()
fig.add_trace(go.Bar(x=df_mean['month'],
                     y=df_mean['スノーピーク'],
                     name='スノーピーク')
)
fig.add_trace(go.Bar(x=df_mean['month'],
                     y=df_mean['ANA'],
                     name='ANA')
)
fig.add_trace(go.Bar(x=df_mean['month'],
                     y=df_mean['ぐるなび'],
                     name='ぐるなび')
)

すると以下のような棒グラフが作成できます。

これだと横軸が何かもわからないので、簡単に装飾をしていきましょう。

以下を対応したいと思います。

  • マーカーの色を変える
  • 幅を変える
  • カーソルを当てたときの表示を少しわかりやすくする。
  • タイトルを付ける
  • y軸にラベルを付ける

ここでは、add_traceを使ってデータをプロットし、update_layoutでレイアウトを設定する方法を使います。

add_traceを使わない場合は、data=go.Bar(...)でデータを設定するのと同様に、layout=go.Layout(...)でレイアウトを設定し、go.Figure(data, layout)として渡してやります。

fig = go.Figure()
months = [f'{month}月' for month in df_mean['month']]
fig.add_trace(go.Bar(x=months,
                     y=df_mean['スノーピーク']*100,
                     marker_color='#87cefa',
                     name='スノーピーク')
)
fig.add_trace(go.Bar(x=months,
                     y=df_mean['ANA']*100,
                     marker_color='#90ee90',
                     name='ANA')
)
fig.add_trace(go.Bar(x=months,
                     y=df_mean['ぐるなび']*100,
                     marker_color='#d2b48c',
                     name='ぐるなび')
)
fig.update_traces(width=0.25,
                  hovertemplate='%{x}: %{y:0.2f}%')
fig.update_layout(title='2020年の月ごとのリターンの平均',
                  yaxis={'title': '月次リターン平均(%)'},
                  legend=dict(orientation='h',
                              xanchor='right',
                              x=1,
                              yanchor='bottom',
                              y=1.05))

まず、marker_colorを指定してマーカーの色を変えています。

次にfig.update_tracesですべてのグラフをまとめて幅を0.25に更新しています。

同様に、カーソルを当てた際の表示方法をhovertemplateを使って変更しています。

hovertemplateは%{}で変数を囲むことにより、その変数を表示します。y:0.2fはyの値の書式を小数点2桁までに変えています。

最後にfig.update_layoutを使って、titleでタイトルの追加、legendで凡例を修正しています。

凡例は、orientation='h'とすることで、水平方向に並べた凡例にしています。

xanchor='right'は右寄せにし、xを1にすることで一番右に寄せています。

yanchorは下寄せにしていますが、y=1.05を指定することでグラフエリアより少し上の部分にいくように指定しています。

以上で、作成できるグラフは以下のようになります。

テキストの表示

では、棒グラフの上にテキストを表示させましょう。

基本的にはtexttemplatetextpositionを使います。

おまけとして、textfontでテキストの色を変えます。

コードは次のようになります。ハイライト部分が主な修正点です。

fig = go.Figure()
df_mean = df_mean.query('month>=8')
months = [f'{month}月' for month in df_mean['month']]
fig.add_trace(go.Bar(x=months,
                     y=df_mean['スノーピーク']*100,
                     marker_color='#4169e1',
                     textfont={'color': '#4169e1'},
                     name='スノーピーク')
)
fig.add_trace(go.Bar(x=months,
                     y=df_mean['ANA']*100,
                     marker_color='#006400',
                     textfont={'color': '#006400'},
                     name='ANA')
)
fig.add_trace(go.Bar(x=months,
                     y=df_mean['ぐるなび']*100,
                     marker_color='#d2b48c',
                     textfont={'color': '#d2b48c'},
                     name='ぐるなび')
)
fig.update_traces(width=0.25,
                  hovertemplate='%{x}: %{y:0.2f}%',
                  texttemplate='%{y:0.2f}%',
                  textposition='outside')
fig.update_layout(title='2020年8月以降のリターンの平均',
                  yaxis={'title': '月次リターン平均(%)'},
                  legend=dict(orientation='h',
                              xanchor='right',
                              x=1,
                              yanchor='bottom',
                              y=1.05),
                  )

texttemplate、textpositionは3つのデータに共通なのでfig.update_tracesでまとめて設定しています。

texttemplateはhovertemplateと同様に%{}で変数を囲むことによって表示方法を設定します。

textpositionはテキストの表示場所を設定し、以下の設定が可能です。

  • inside
    棒グラフの内側に表示します。
  • outside
    棒グラフの外側に表示します。
  • auto
    自動で設定されます。
  • none
    表示しません。

これで表示されるグラフは次のようになります。

別途、テキスト情報を設定したい場合は、textという引数にリストで表示させたいテキスト情報を設定してやります。

水平方向の棒グラフ

水平方向のグラフの方が見やすい場合も多々あります。

私は、特徴量の重要度を可視化する際には、特徴量名が長かったり、特徴量が多かったりで、水平方向のグラフをよく使います。

水平方向にするには、レイアウトの指定のときにorientationを"h"に設定するだけです。

ただし、x軸とy軸の設定がすべて逆になりますので、そこだけご注意ください。

fig = go.Figure()
#df_mean = df_mean.query('month>=8')
months = [f'{month}月' for month in df_mean['month']]
fig.add_trace(go.Bar(x=df_mean['スノーピーク']*100,
                     y=months,
                     marker_color='#87cefa',
                     textfont={'color': '#87cefa'},
                     name='スノーピーク')
)
fig.add_trace(go.Bar(x=df_mean['ANA']*100,
                     y=months,
                     marker_color='#90ee90',
                     textfont={'color': '#90ee90'},
                     name='ANA')
)
fig.add_trace(go.Bar(x=df_mean['ぐるなび']*100,
                     y=months,
                     marker_color='#d2b48c',
                     textfont={'color': '#d2b48c'},
                     name='ぐるなび')
)
fig.update_traces(width=0.25,
                  hovertemplate='%{y}: %{x:0.2f}%',
                  texttemplate='%{x:0.2f}%',
                  textposition='outside',
                  orientation='h')
fig.update_layout(title='2020年8月以降のリターンの平均',
                  xaxis={'title': '月次リターン平均(%)'},
                  legend=dict(orientation='h',
                              xanchor='right',
                              x=1,
                              yanchor='bottom',
                              y=1.05),
                  width=800, 
                  height=800,
                  plot_bgcolor='white'
                  )

fig.update_layout()にorientation='h'を追加し、あとはx軸の設定とy軸の設定をすべて入れ替えます

また、グラフのサイズを変更するために、fig.update_layoutでwidthheightを指定しています。

関係ありませんが、グラフをすっきりさせるために、plot_bgcolor='white'として、背景色も変えています。

すると以下のようなグラフが出来上がります。

その他

他には以下のような設定が有用です。

積み上げ棒にしたい場合は、fig.update_layout(barmode='stack')とします。

バーごとに色、幅を変えるには、marker_colorやwidthに、各要素ごとの色や幅をリストで渡してあげます。
以下のようなコードになります。

fig = go.Figure()
df_mean = df_mean.query('month>=8')
months = [f'{month}月' for month in df_mean['month']]
fig.add_trace(go.Bar(x=months,
                     y=df_mean['スノーピーク']*100,
                     marker_color=['#87cefa', '#00bfff', '#6495ed', '#4169e1', '#0000ff'],
                     width=[0.1, 0.2, 0.3, 0.4, 0.5],
                     textfont={'color': '#87cefa'},
                     name='スノーピーク')
)
fig.update_layout(title='2020年8月以降のリターンの平均',
                  yaxis={'title': '月次リターン平均(%)'},
                  legend=dict(orientation='h',
                              xanchor='right',
                              x=1,
                              yanchor='bottom',
                              y=1.05),
                  )

まとめ

今回は、plotlyを使った棒グラフを作成しました。

線グラフや散布図の作成を理解していれば、もう難しいところはそれほどないかと思います。

私はあまりセンスがありませんが、皆さまは分析をより効率的に行うことができる、相手に訴えかけられるようなキレイでインパクトのあるグラフを作成していただければと思います。

では!

-plotly入門
-, ,