Pythonを扱っていて、matplotlibで円グラフを作成していた際に、円グラフ上にパーセントだけではなく、元のデータも一緒に表示するのに苦労したので、その方法について書いていきます。
▲最終的な目標は、上の画像のように、パーセントだけでなく元のデータも円グラフ上に出力することです。
円グラフ上にパーセントを表示する方法
▲このようなデータフレームをdfに入れているとします。
まずは準備段階として、このデータを使って、各店舗の売上の割合を円グラフに表示する方法について書いていきます。
import pandas as pd import matplotlib.pyplot as plt shops = df['店舗'] sales = df['売上'] plt.rcParams['font.family'] = "Arial Unicode MS" #日本語を出力するためのコード plt.style.use('ggplot') plt.rcParams.update({'font.size':15}) size=(9,5) ###pie### col = ['orangered','yellowgreen','pink','lightskyblue', 'gold'] #色の指定はお好みで plt.figure(figsize=size,dpi=100) plt.pie(sales, colors=col, counterclock=False, startangle=90, autopct=lambda pct:'{:.1f}%'.format(pct) if pct>=5 else '', pctdistance=0.7) #パーセント表示は小数点第1位まで。パーセント表示。5%未満の場合は円グラフ上に出力しないようにしています plt.subplots_adjust(left=0,right=0.7) plt.legend(shops,fancybox=True,loc='center left',bbox_to_anchor=(0.9,0.5)) plt.axis('equal') plt.title("店舗別の売上割合", fontsize=15)
▲パーセントが一緒に出力されている円グラフが出力されます。
plt.pie(sales, colors=col, counterclock=False, startangle=90, autopct=lambda pct:'{:.1f}%'.format(pct) if pct>=5 else '', pctdistance=0.7)
▲{:.1f}
は、小数点第1位までパーセント表示することを意味しています。
if pct>=5 else ''
によって、5パーセント未満の割合については表示しないようにしています。表示したい場合はこのコードを取り除けばokです。
円グラフ上にパーセントだけでなく、元の数値データも一緒に表示する方法
続いて先程の円グラフ上に、パーセントだけではなく、元データも一緒に表示する方法について書いていきます。
変更点は3箇所です。
- インポート部分。
import numpy as np
を追加 - 関数
abs_funcを定義
plt.pie
のところ
1つ目はimport numpy as np
を追加しただけです。
2つ目は、関数として、abs_func
を定義しています。
#%と元の数値データを同時に出力する
def abs_func(pct, abs_values):
absolute = int(np.round(pct/100.*np.sum(abs_values)))
<return "{:.1f}%\n({:,}円)".format(pct, absolute)
▲関数 abs_func
は、pct
(パーセント)とabs_values
(元の数値データリスト(今回で言えば、[500000, 300000, 200000, 150000, 50000])を引数として、
パーセントと元の数値データを返す関数です。
\n
は改行コードです。
{:,}
では、売上の数値データを3桁ごとにカンマ区切りが入るようにしています。(500000なら500,000となります。)
3つ目はplt.pie
の中身のautopct
が先程とは異なります。
autopct=lambda pct: abs_func(pct, sales) if pct>=5 else ''
▲2つ目の部分で説明した abs_func
関数を使うことにより、autopct
に、パーセントと元の数値データを渡しています。
1〜3つ目の変更点を施したコードが以下になります。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
shops = df['店舗']
sales = df['売上']
plt.rcParams['font.family'] = "Arial Unicode MS"#日本語を出力するためのコード
plt.style.use('ggplot')
plt.rcParams.update({'font.size':15})
size=(9,5)
#%と元の数値データを同時に出力する
def abs_func(pct, abs_values):
absolute = int(np.round(pct/100.*np.sum(abs_values)))
return "{:.1f}%\n({:,}円)".format(pct, absolute)
###pie###
col = ['orangered','yellowgreen','pink','lightskyblue', 'gold']
plt.figure(figsize=size,dpi=100)
plt.pie(sales, colors=col, counterclock=False, startangle=90, autopct=lambda pct: abs_func(pct, sales) if pct>=5 else '',
pctdistance=0.7)
plt.subplots_adjust(left=0,right=0.7)
plt.legend(shops,fancybox=True,loc='center left',bbox_to_anchor=(0.9,0.5))
plt.axis('equal')
plt.title("店舗別の売上割合", fontsize=15)
これを実行すると、以下のグラフが出力されます。
▲パーセント表示とともに、元の数値データも一緒に表示され、わかりやすさが増しました。
参考 matplotlibでいい感じの円グラフを書く – Qiita
参考 Labeling a pie and a donut — Matplotlib 3.5.1 documentation
コメント