【Python】面グラフ・層グラフを描画する方法
Pythonのmatplotlibを使った、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)を描画する方法を調べてみました。 面グラフとして有名な積み上げ面グラフ、積み上げ100%面グラフ の特徴を比較した後、それぞれを描画するソースコードを記載します。 加えて、モノクロ印刷時にグラフを見やすくするハッチング(グラフの面ごとの模様・柄を設定)の方法も記載します。
使用データ
政府統計の総合窓口e-Statから取得できる統計名「成果物卸売市場調査 長期累年」を使用します。具体的に使用するデータ項目は、次の通りです。
面グラフ・層グラフとは
本記事では、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)のうち積み上げ面グラフ、積み上げ100%面グラフを対象とします。
上記のデータを面グラフで表現すると、次のようになります。 ちなみに、描画にはExcelを使用しました。
それぞれの特徴をまとめると、下表のようになります。いずれのグラフもデメリットは存在しますが、双方を組み合わせることでお互いのデメリットを補うことができます。
本題から脱線しますが、たけのこの卸売量は極端に少ないですね笑 高級品として扱われる意味が分かります。
項目 | 積み上げ面グラフ | 積み上げ100%面グラフ |
---|---|---|
図 | 左図 | 右図 |
表現する対象 | 変化量の構成 | 構成比率の変化 |
メリット | 全体、構成要素ごとの変化量が分かりすい | 構成比率・変化の要因が分かりやすい |
デメリット | 全体が変化した要因が分かりにくい | 変化量が分からない |
Pythonによる面グラフの描画方法
ここでは、Pythonによる面グラフの描画方法をまとめています。
内容としては、上で登場した積み上げ面グラフ、積み上げ100%面グラフと積み上げ面グラフ(ハッチング)です。 ハッチングとは、面グラフの面に模様・柄を設定するもので、モノクロ印刷時にとても見やすいです。(弊社はカラー印刷に制限があるので。。。)
積み上げ面グラフ
具体的なソースコードと積み上げ面グラフは、次の通りです。 また、グラフの画質や日本語表記などのグラフの整形方法の詳細は、参考URLをご確認下さい。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) plt.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor=(0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
- matplotlib よく使うグラフまとめ(折れ線、積み上げ面グラフ) - Qiita
- matplotlibで軸の値が小数になったりオフセット表現になったりするのを止める方法 - minus9d's diary
- 【超簡単】たったの2ステップで matplotlib の日本語表記を対応させる方法 | YOLO – 人工知能の導入録
- チラシ裏のラクガキ: Matplotlibの高解像度画像保存
積み上げ100%面グラフ
積み上げ100%面グラフは、積み上げ面グラフと異なり、描画する前に数量を割合に変換(11行目)します。 逆に11行目以外は、積み上げ面グラフと同じソースコードです。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) df = df.apply(lambda x:x/sum(x),axis=1) #ここを追加 plt.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor=(0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
積み上げ面グラフ(ハッチング)
ハッチング(hatch)とは、面グラフの面に模様・柄を設定するもので、モノクロ印刷時にとても有効です。 上記の積み上げ面グラフと比較すると、変更点が分かりやすいと思います。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) hatch_list = ['xx', '\\', '//', '||', '--', '..', '++'] fig, ax = plt.subplots() stacks = ax.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) for (stack, hatch) in zip(stacks, hatch_list): stack.set_hatch(hatch) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor = (0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
- Python matplotlibで棒グラフ(ハッチングと2軸グラフの凡例) - Qiita
- python - Matplotlib: stackplot with different hatches - Stack Overflow
まとめ
Pythonのmatplotlibを使った、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)を描画する方法を調べました。 面グラフとして有名な積み上げ面グラフ、積み上げ100%面グラフ の特徴を比較した後、それぞれを描画するソースコードをまとめました。 加えて、モノクロ印刷時にグラフを見やすくするハッチング(グラフの面ごとの模様・柄を設定)の方法もまとめました。