さて、今回は棒グラフ、線グラフよりはマニアックですがPython Plotlyを使ったウォーターフォール・チャート(Waterfall Chart)の作成方法を紹介します。
ウォーターフォール・チャートは主に企業の決算情報のように、何が要因でどのように増減したか?を視覚化するものです。
例えば、こちらはトヨタ自動車の決算説明資料にある営業利益の増減を表したグラフです。

前年度に23,992億円だった営業利益が、為替の変動で▲2,550億円、原価改善や諸経費の低減でそれぞれ+1,500億円、+700億円となるなどして、最終的には21,977億円の減少になったということが非常にわかりやすくなっています。
ここでは、このウォーターフォール・チャートをPlotlyを使って作成していきたいと思います。
公式HPの解説はこちらです。
基本的なプロット方法
では、まずはいつも通りplotly.graph_objectsをインポートしましょう。
import plotly.graph_objects as go
わかりやすくするために、先にデータを作成しておきます
x = ['19年度営業利益', '為替変動', '原価改善', '販売面の影響', '諸経費の増減', 'その他', '20年度営業利益'] y = [23992, -2550, 1500, -2100, 700, 436, 21977] measure = ["absolute", "relative", "relative", "relative", "relative", "relative","total"]
xに項目名を設定しています。
yにはxに対応する値を設定しています。
次がポイントですが、measureに対応する項目が絶対的な数値なのか、それとも相対的な増減に関する数値なのかを設定します。
この場合、「19年度営業利益」、「20年度営業利益」は絶対的な値なので“absolute”を、それ以外については増減なので“relative”を設定します。
あとは、go.Waterfall()でこれらのプロパティを設定して描画します。
ここでは、fig.add_trace()を使います。
fig = go.Figure()
fig.add_trace(go.Waterfall(
x=x,
measure=measure,
y=y,
))
fig.show()
すると以下のようなグラフが作成されます。

スタイリング
テキスト情報の表示
とりあえず、ウォーターフォール・チャートを描画することができましたが、さすがにこれではいくらの影響があったのかまったくわかりません。
そこで、最低限の作業として棒グラフのところに数値を表示していく必要があります。
これは、Plotlyのテキスト設定で可能です。
まずは、表示したいテキストを用意しましょう。
yの値をそのまま設定してもいいのですが、見やすくするために少しだけスタイリングします。
import numpy as np
def styling_text(x, is_relative):
sign = np.sign(x)
if sign == 1:
if is_relative:
return f'+{x:,}億円'
else:
return f'{x:,}億円'
elif sign == -1:
return f'▲{np.abs(x):,}億円'
text = [styling_text(value, measure_=='relative') for value, measure_ in zip(y, measure)]
では、これをtextという引数に設定し、textpositionを"outside"にしましょう。
fig = go.Figure()
fig.add_trace(go.Waterfall(
x=x,
measure=measure,
y=y,
text=text,
textposition='outside',
))
fig.show()
これで、増減の金額とその要因がわかるようになりました。

色を変える
合計(absolute)と増加、減少によって色や線を変えることが可能です。
これには、totals, decreasing, increasingをそれぞれについてmarkerプロパティを設定します。
また、棒と棒の間の線はconnectorというプロパティを設定することにより線の色や形を変えることができます。
fig = go.Figure()
fig.add_trace(go.Waterfall(
x=x,
measure=measure,
y=y,
text=text,
textposition='outside',
width=0.5,
decreasing = dict(marker={'color': 'lightgrey'}),
increasing = dict(marker={'color': 'lightblue'}),
totals = dict(marker={'color': 'royalblue'}),
connector = {'line': {'width': 1, 'color':'lightgrey', 'dash': 'solid'}}
))

可読性を高める
では、もう少し無駄なものを取り除いて、可読性を高めていきましょう。
以下はレイアウトや軸の設定、アノテーションの設定の話なのでウォーターフォール・チャート固有のものではありません。
ご興味がある方は以下をご参照ください。
レイアウトの設定 ⇒ Python Plotly入門 – レイアウト設定
軸の設定 ⇒ Python Plotly入門 – 軸の設定
では、以下のコードでレイアウトなどを設定しましょう。
あまり工夫して書いていないので冗長になっていますし、皆さんはもっとセンスのあるグラフにできると思います。
fig = go.Figure()
fig.add_trace(go.Waterfall(
x = x,
measure = measure,
y = y,
text = text,
textfont=dict(size=15,
color=['royalblue', 'grey', 'lightblue', 'grey', 'lightblue', 'lightblue', 'royalblue']),
textposition='outside',
width=0.5,
decreasing = dict(marker={'color': 'lightgrey'}),
increasing = dict(marker={'color': 'lightblue'}),
totals = dict(marker={'color': 'royalblue'}),
connector = {'mode': 'between', 'line': {'width': 1, 'color':'lightgrey', 'dash': 'solid'}}
))
fig.update_layout(title=dict(text='<b>連結営業利益増減要因',
font_color='grey',
font_size=24),
plot_bgcolor='white',
yaxis=dict(visible=False,
range=(0, 27000)),
xaxis=dict(tickfont_color='white',
showline=True,
linecolor='lightgrey',
linewidth=1,
),
width=1000)
fig.add_annotation(text='<b>2020年度営業利益',
font=dict(color='royalblue',
size=15),
showarrow=False,
x=0,
y=21992+5000,)
fig.add_annotation(text='<b>為替変動の影響',
font=dict(color='grey',
size=15),
showarrow=False,
x=1,
y=21992-2550-1000,)
fig.add_annotation(text='<b>原価改善の努力',
font=dict(color='lightblue',
size=15),
showarrow=False,
x=2,
y=21992-2550+1500+5000,)
fig.add_annotation(text='<b>販売面での影響',
font=dict(color='grey',
size=15),
showarrow=False,
x=3,
y=21992-2550+1500-2100-1000,)
fig.add_annotation(text='<b>諸経費の減少',
font=dict(color='lightblue',
size=15),
showarrow=False,
x=4,
y=21992-2550+1500-2100+700+5000,)
fig.add_annotation(text='<b>その他',
font=dict(color='lightblue',
size=15),
showarrow=False,
x=5,
y=21992-2550+1500-2100+700+436+5000,)
fig.add_annotation(text='<b>2021年度営業利益',
font=dict(color='royalblue',
size=15),
showarrow=False,
x=6,
y=21992-2550+1500-2100+700+436+5000,)
fig.show()
これで以下のようなグラフが出来上がります。

何となく見やすくなったのではないでしょうか?
トヨタ自動車の決算説明資料のように、もっと説明を付けることにより、図を見るだけで苦労なく増減要因が理解できるようになると思います。
まとめ
今回は増減要因を見やすくするウォーターフォール・チャートについて紹介しました。
他にもカーソルを当てたときに、より詳細な説明を表示するなどにより、Plotlyのインタラクティブな可視化のメリットをより享受できると思います。
皆さまも仕事などで目的にあった可視化をしていただければと思います。
あとがき
当初は私がキャンプ好きで、業績が好調かつハイセンスなスノーピークの決算情報を使おうと思っていました。
そこで決算情報をスノーピークのHPに見にいったのですが、IRページにあった売上等のグラフはこちらでした。

(そういうことを言う場ではないので)あまり言いたくないのですが、品質やセンスにこだわったキャンプ用品とは違い良くないグラフですね…。
さすがに決算説明資料はちゃんとされていましたが(すごくキレイでした)、ホームーページの方はこんなExcelから適当に貼り付けた可読性が極めて低いグラフが使われているのは驚きです。
なぜ可読性が低いか?、なぜこのようなグラフは良くないかについては、以下の書籍などを参考にしていただければと思います。
グラフを人に見せる人は必見の内容が詰まっています。
上記の本は英語なので抵抗がある方は以下の本がわかりやすいです。ただ上記の本は読む価値は非常に高いと思います。
他にもこういうグラフは作成してはいけません、というものを紹介しているので、こちらの記事もご参照ください。
少しの手間で大勢の人がグラフを読む時間や負担を軽減することができますので、グラフを作成する人は是非学んでいただけると得るものがすごく多いと思います!
ではまた!
