Matplotlib & Seaborn 入門講座 | 07.【実践】Pythonを使った円グラフの作成方法

挨拶

こんにちは。キノコードです。
Matplotlib & Seaborn入門講座の7回目です。
前回のレッスンでは、円グラフの作成方法について解説しました。
この動画では、前回の動画で説明した内容をもとに、実践的なデータを使って円グラフを作成、また前回のレッスンでは説明しなかった二重ドーナツの作成方法などをしていきたいと思います。
実践的なデータを通して仕事などへのイメージを沸かしていただければと思います。
なお、キノコードでは、YouTubeのメンバーシップを募集しています。
キノコードを応援してくださる方は、メンバーになるをクリックをお願いします。
メンバーシップをはじめた理由などの動画もありますので、そちらもご視聴ください。
概要欄にURLを貼っておきます。
それではレッスンスタートです。

レッスンで使ったファイルはこちら

■保存方法
Mac:右クリック⇒「リンク先を別名で保存」
Windows:右クリック⇒「名前を付けてリンク先を保存」
Jupyter Labのファイルはこちら
CSVファイルはこちら

ライブラリインポート

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

それでは、ライブラリをインポートする記述をします。
pandasをpdという名前でインポートします。
pandasを使うことで、csvやExcelファイルなどのデータを簡単に読み込み、効率的にデータ加工をすることができます。
さらに、matplotlibの中のpyplotをpltという名前でインポートします。
最後のこの記述は、notebook内にグラフを表示させるための記述です。
実行します。
インポートが完了しました。

データ読み込み

df = pd.read_csv('data.csv')

続いて、pandasのread_csvメソッドを使ってcsvファイルを読み込む記述をします。
こちらのcsvファイルは、キノコードのwebサイトからダウンロードできます。
丸括弧の中に読み込むファイル名を記述し、実行します。
read_csvメソッドの詳しい使い方については、pandas入門講座で説明をしています。
詳しく知りたい方は、そちらもご覧ください。

df.head()

それでは、dfの中身を確認してみましょう。
headメソッドで上位5件を表示させてみます。
実行します。
データが格納されているようです。

商品分類ごとの売上金額合計算出

df_sum = df[['商品分類','売上金額']].groupby('商品分類').sum()
df_sum

続いて、グラフを作成しやすいように、データを加工しましょう。
pandasのgroupbyメソッドを使って、商品分類ごとの売上金額の合計を算出します。
groupbyの詳しい使い方については、pandas入門講座でも解説をしています。
そちらもご覧ください。
dfアンダースコアsumという変数に、商品分類ごとの売上金額の合計を格納します。
二重括弧の中に、商品分類と売上金額、groupbyの丸括弧の中には商品分類と記述します。
最後に、合計を意味するsumを書いて丸括弧です。
実行します。
支店ごとのデータフレームを作成できました。

売上金額を降順にする

df_sum = df_sum.sort_values(by='売上金額', ascending=False)
df_sum

作成したデータフレームを、降順に並べ替えてみましょう。
大きいものから小さいものへの並び替えを降順と言います。
pandasの、sort_valuesメソッドを使って並び替えていきます。
sort_valuesについてもpandas入門講座で詳しく解説をしています。
是非そちらもご覧ください。
byという引数に、並び替えをする売上金額の列を渡します。
ascendingイコールFalseとすることで降順になります。
Trueにすると昇順です。
実行します。
並べ替えができているようです。

円グラフ作成

!pip install japanize_matplotlib
import japanize_matplotlib

value = df_sum['売上金額']
label = df_sum.index

plt.pie(x=value, labels=label)
plt.show()

それでは、円グラフを作成する記述をしましょう。
日本語を表示させるために、japanize_matplotlibをインポートします。
なお、googlecolabを使用している方や、インストールがまだの方は、こちらの記述(#)をしてください。
続いて、先ほど作成したデータフレームの売上金額の列を、valueという変数に代入します。
インデックスの商品分類は、labelという変数に代入しておきましょう。
円グラフの作成は、pltドットの後にpieと記述します。
pieメソッドの引数xには、先ほど代入したvalueを、labelsにはlabelを渡します。
実行します。
円グラフを作成できました。

plt.pie(x=value)
plt.legend(label)
plt.show()

凡例を一箇所にまとめて表示させてみましょう。
先ほどのpie丸括弧の中で記述したlabelsは削除しておきます。
凡例を表示させるための記述は、legendです。
丸括弧の中に、先ほど代入したlabelを記述します。
実行します。
凡例を一箇所にまとめることができました。
しかし、このままでは円グラフと重なってしまっています。
凡例の位置を調整してみましょう。


参考:(書籍)「データ分析者のためのPythonデータビジュアライゼーション入門 コードと連動してわかる可視化手法」p104-105
(matplot,legend公式): https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.legend.html


plt.pie(x=value)
plt.legend(label,bbox_to_anchor=(1,1), loc='upper left')
plt.show()

bbox to anchor(ビーボックス トゥ アンカー)で凡例の位置を指定することができます。
凡例を円グラフの左上に表示させたい場合は、(0,1)、右上に表示させたい場合は(1,1)のようにx,yの順に座標軸で指定することができます。
今回は右上を指す(1,1)とします。
そして、凡例のどの位置をこの座標に合わせるかを指定します。
例えば、「center」とすれば凡例の中心位置を座標に合わせたり、「lower right」とすれば凡例の右下を合わせることができます。
では、「upper left」として、凡例の左上を座標(1,1)に合わせる指定をしてみましょう。
実行します。
凡例をこのように表示できました。

plt.pie(x=value, autopct='%1.1f%%')
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.show()

続いて、グラフの中にパーセンテージを表示させてみましょう。
pieの丸括弧の中に、autopctイコールと記述します。
パーセントの後に、小数点以下第1位までを示す1.1fと書いてさらにパーセントを2つ記述します。
実行します。
グラフにパーセンテージが表示されました。

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.show()

matplotlibで円グラフを作成すると、デフォルトでは時計の3時の位置から反時計回りで表示されます。
これを、12時の位置から時計回りで表示させてみましょう。
開始位置を調整するにはstartangleに値を代入します。
pieの丸括弧の中に、startangleイコール90と記述することで、スタートが12時の位置になります。
また、counterclockイコールFalseとすることで、時計回りでグラフを表示させることができます。
実行します。
12時の位置から始まる円グラフを作成できました。

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.show()

グラフにタイトルを追加しましょう。
titleと書いた丸括弧の中に、好きな名前をシングルコーテーションでくくります。
fontsizeを15としておきましょう。
実行します。
タイトルを表示できました。

カラー変更

import numpy as np

cmap = plt.get_cmap("Paired")
color = cmap(np.arange(3))

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False,
        colors=color)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.show()

続いて、グラフの色を変更してみましょう。
今回は、データ分の色を配列で設定するのではなく、matplotlibに用意されているカラーマップを使って色を変更してみます。
まず、numpyをnpという名前でインポートします。
続いて、cmapという変数に、指定したいカラーマップを代入する記述をします。
円グラフでは、これら(colormaps_reference.png)のカラーマップを指定できるので、お好きな色を試してみてください。
今回は、paired(ぺアード)を指定してみます。
続いて、グラフの要素は3つあるので、numpyのarange(エーレンジ)関数を使って3つ分の色を生成し、colorという変数に代入しておきます。
pie丸括弧の中に、引数colorsを記述しイコール、先ほど設定したcolorを渡します。
実行します。
グラフの色を変更できました。

円グラフの一部切り取り

cmap = plt.get_cmap("Paired")
color = cmap(np.arange(3))

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False, 
        colors=color, explode=[0, 0.3, 0])
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.show()

次に、円グラフの一部を切り取って強調させてみましょう。
今回は、ボトムスを切り出してみます。
pieの丸括弧の中に、explodeイコールと記述し角括弧、3つの要素の中心からの位置を、数値で設定します。
円グラフの中心が0で、円周が1です。
つまり、今回は2つ目の要素を切り出したいので、角括弧の中の2つ目の数値を0.3としてみます。
実行します。
2つ目の要素が切り出されました。

cmap = plt.get_cmap("Paired")
color = cmap(np.arange(3))

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False, 
        colors=color,explode=[0, 0.3, 0], shadow=True)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.show()

円グラフに影をつけることもできます。
pieの丸括弧の中に、shadowイコールTrueと記述します。
実行します。
グラフに影がつきました。

グラフ保存

cmap = plt.get_cmap("Paired")
color = cmap(np.arange(3))

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False, 
        colors=color,explode=[0, 0.3, 0], shadow=True)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.savefig('PieGraph.png')

作成したグラフを保存しましょう。
savefigの丸括弧の中に好きなファイル名をシングルコーテーションでくくります。
今回はpng形式で保存してみます。
他にも、jpegやpdfを指定できます。
実行します。
グラフを保存できました。

ドーナツ型円グラフ

cmap = plt.get_cmap("Paired")
color = cmap(np.arange(3))

plt.pie(x=value, autopct='%1.1f%%', startangle=90, counterclock=False, colors=color, pctdistance=0.75)
plt.pie([100], colors='white', radius=0.5)
plt.legend(label, bbox_to_anchor=(1,1), loc='upper left')
plt.title('商品分類別売上シェア', fontsize=15)
plt.show()

ドーナツ形のグラフを作成してみましょう。
matplotlibでは、後から描いた記述が上書きされます。
従って、先ほど作成した円グラフに、背景と同じ色の円を重ねることで、ドーナツ型の円グラフを作成できます。
まず、引数pctdistanceでパーセンテージの表示位置を調整しておきます。
円の中心が0、円周が1です。
従って0.75の位置に指定してみます。
2つ目のpltドットpie丸括弧、丸括弧の中に100%の白い円を作成する記述をします。
100%の円を描くために、角括弧の中に100と指定をします。
円を背景と同じ白塗りにするために、colorsにはwhiteを指定します。
radius(レィディアス)で円の大きさを指定できます。
今回は0.5とします。
実行します。
ドーナツ型のグラフを作成できました。

二重ドーナツ

df_sum2 = df[['商品分類', '商品名', '売上金額']].groupby(['商品分類', '商品名']).sum()
df_sum2 

次に、ドーナツグラフを2つ重ねて、合計と内訳を表示するグラフを作成してみましょう。
商品分類別の売上の内訳として、商品名を追加してみましょう。
商品分類と商品名で集計したデータを、df_sum2という変数に代入します。
実行します。
商品分類と商品名の2つの項目で集計ができました。

# 色を設定
cmap1 = plt.get_cmap("tab10")
cmap2 = plt.get_cmap("tab20c")
color1 = cmap1(np.arange(3))
color2 = cmap2([0,1,4,5,8,9,10])
# 商品名別
label1 = ['アウター', 'トップス', 'ボトムス']
value2 = df_sum2['売上金額']
label2 = labels=df_sum2.index.get_level_values('商品名')

# 1つ目のグラフ
plt.pie(x=value, labels=label1, startangle=90, counterclock=False, colors=color1)
# 2つ目のグラフ
plt.pie(x=value2, labels=label2, startangle=90, counterclock=False, colors=color2,
        radius=0.8, labeldistance=0.6)
# 中心の白い円のグラフ
plt.pie([100], colors='white', radius=0.5)

plt.show()

では、二重ドーナツグラフを描いてみましょう。
まずは、グラフの色の指定をします。
カラーサンプルから2つ選択し、それぞれ変数に代入します。
また、商品名別の集計したデータを変数label1、value2、label2に代入します。
先ほど集計したdf_sum2はインデックスが2列のマルチインデックスのデータフレームでした。
インデックス名として商品名を取得したいので、このように記述します。

1つ目のグラフを描きます。
ここはこれまでと同様に、商品分類別の売上金額のグラフを作成する記述です。
ラベルにlabel1を指定し、グラフの色は、先ほど設定したcolor1を指定しましょう。
次に、2つ目のグラフとして、商品別の売上金額のグラフを作成します。
要素の値にはvalue2を指定し、ラベルにはlabel2を指定します。
スタートの位置とデータを時計回りにする記述は同じです。
グラフの色にはcolor2を指定します。
そして、引数レイディアスで、1つ目のグラフより半径を小さく指定します。
ここでは0.8としましょう。
ラベルの位置を引数labeldistanceで0.6と指定します。
この数値は、円の中心が0、円周が1です。
最後に、ドーナツの真ん中の白い円を記述します。
半径は先ほどと同様に0.5としましょう。
実行します。
外側が合計、内側に内訳を表示した二重ドーナツが描けました。

挨拶

実践的なデータをもとに、円グラフの作成方法についての説明は以上です。
難しい点などありませんでしたでしょうか?
キノコードではmatplotlibやSeabornのレッスンだけではなく、仕事の自動化のレッスン、人工知能のレッスンなども配信しています。
キノコードの新着動画はチャンネル登録をしていただければ、通知が届きますので、ぜひチャンネル登録をお願いします。
それでは、次のレッスンでお会いしましょう。

レッスンで使ったファイルはこちら

■保存方法
Mac:右クリック⇒「リンク先を別名で保存」
Windows:右クリック⇒「名前を付けてリンク先を保存」
Jupyter Labのファイルはこちら
CSVファイルはこちら