スポンサーリンク

Python初心者でも簡単!matplotlibを使った円グラフとドーナツグラフの描き方を徹底解説

2023年3月17日

 Pythonでデータ処理を行った結果を簡単にグラフに出力したいと思ったことはありませんか?

 この記事では、初心者の方向けに、Pythonのmatplotlibパッケージを使って円グラフを簡単に描く方法を最新の情報をもとに丁寧に解説していきます。加えて、ドーナツグラフについても解説します。

 ワンステップずつコードを解説しているのでどなたでもPythonで円グラフとドーナツグラフが描けるようになります!

 是非、この機会にmatplotlibパッケージを使った円グラフにトライしてみましょう。



ドーナツグラフを描く方法をすぐにご覧になりたい方はこちらをクリック。



準備

 Pythonの実行環境の構築やmatplotlibパッケージ、pandasパッケージのインストールがまだの方は以下の記事を参考にしてPythonの実行環境の構築とmatplotlibパッケージ、pandasパッケージのインストールを済ませてください。

円グラフ

 最初に、円グラフの描き方を解説していきます。

カスタマイズ前の円グラフ

# パッケージをインポートする。
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import rcParams as rcp

# フォントを設定する。
rcp['font.family'] = 'sans-serif'
rcp['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']

# Figureを作成する。
fig = plt.figure()
# Axesを作成する。
ax = fig.add_subplot(111)

# Figureの解像度と色を設定する。
fig.set_dpi(100)
fig.set_facecolor("whitesmoke")

# Axesのタイトルと色を設定する。
ax.set_title("トロピカルフルーツの消費量(重量ベース)")
ax.set_facecolor("whitesmoke")

# データを用意する。
data = {
    "Fruit": ["Banana", "Mango", "Durian", "Papaya", "Pineapple"],
    "Amount[kg]": [100, 60, 80, 40, 150],
    "Amount[Yen]": [40, 220, 140, 100, 80]}

# データを描画する。
ax.pie(data["Amount[kg]"])

# グラフを表示する。
plt.show()
カスタマイズ前の円グラフ

 上記グラフは、まだなにもカスタマイズをしていない、データとして用意したディクショナリ変数dataの「Amount[kg]」値を単にAxesクラスのpieメソッドで描画しただけのものです。グラフでは、5つのトロピカルフルーツの重量ベースの消費量を円グラフにしました。データとして、各フルーツの重量ベースの消費量と金額ベースの消費量を用意していますが、金額ベースの消費量については次の章で使います。なお、データはすべて架空のものです。

 FigureやAxesの作成、グラフタイトルの設定などグラフの基本的なコードについては説明を省きます。matplotlibパッケージを使ったグラフの基本についてはこちらをご覧ください。

円グラフのカスタマイズ

データのソートと描画

# データを重量ベースの降順でソートする。
dataframe = pd.DataFrame(data)
dataframe1 = dataframe.sort_values(by="Amount[kg]", ascending=False)

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(dataframe1["Amount[kg]"])
データのソートと描画

 pandasパッケージのDataFrameクラスを使ってディクショナリ変数dataの「Amount[kg]」値をキーに降順にソートを行い、その結果を円グラフにします。現時点では、日本ではあまり見られない反時計回りの円グラフになっています。これは、後で時計回りの円グラフに修正します。

 なお、Axesクラスのpieメソッドの返り値を変数patches1とlbl_texts1とpct_texts1へ格納していますが、これらは、後ほど使用します。

ラベルの描画

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"])
ラベルの描画

 キーワード引数labelsを使って各要素のラベルを描画します。ラベルの値には、用意したデータをソートしたものが格納されているディクショナリ変数dataframe1の「Fruit」値を使用しています。

色の変更

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors)
色の変更

 キーワード引数colorsを使って各要素の表示に使用する色を変更します。ここでは、「Set2」というカラーマップを使っています。

 他のカラーマップについてはこちらをご覧ください。円グラフに使用するカラーマップは、Qualitativeに分類されるカラーマップから選ぶことができます。

向きと角度の変更

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors,
    counterclock=False,
    startangle=90)
向きと角度の変更

 キーワード引数counterclockを使って円グラフを時計回りに設定します。また、キーワード引数startangleを使って円グラフの始点を「90度」に設定します。円グラフの要素「Pineapple」が、時計の12時の位置から時計回りに描画されるようになりました。

パーセント表示とラベルの設定

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors,
    counterclock=False,
    startangle=90,
    autopct="%.d%%",
    pctdistance=.8,
    labeldistance=1.15)
パーセント表示とラベルの設定

 キーワード引数autopctを使ってパーセント表示を「小数点以下0桁」で表示しています。また、キーワード引数pctdistanceを使ってパーセント表示の位置を「0.8」に、キーワード引数labeldistanceを使ってラベルの位置を「1.15」に設定しています。キーワード引数pctdistanceとlabeldistanceは円の中心が0で円周上が1となる値です。

各要素のデザイン設定

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors,
    counterclock=False,
    startangle=90,
    autopct="%.d%%",
    pctdistance=.8,
    labeldistance=1.15,
    wedgeprops={"alpha": .8, "linewidth": 1, "edgecolor": "white"},
    shadow=True)
各要素のデザイン設定

 キーワード引数wedgepropsを使って各要素のデザインを設定します。ここでは、透明度を「0.8」に、枠線の幅を「1」に、枠線の色を「white」に設定しています。また、キーワード引数shadowを使って各要素に影をつけています。

 名前つきの色についてはこちらをご覧ください。グラフに使用する色は、この名前つきの色から選択するか、こちらに記載されている種々のフォーマットで指定することができます。

各要素のオフセット設定

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors,
    counterclock=False,
    startangle=90,
    autopct="%.d%%",
    pctdistance=.8,
    labeldistance=1.15,
    wedgeprops={"alpha": .8, "linewidth": 1, "edgecolor": "white"},
    shadow=True,
    explode=(0, .04, 0, 0, 0))
各要素のオフセット設定

 キーワード引数explodeを使って各要素のオフセットを設定しています。ここでは、2つめの要素の「Banana」を「0.04」だけオフセットしています。キーワード引数explodeは、円の中心が0で円周上が1となる値です。

ラベル文字の設定

# ラベルを表示する。
for tx in lbl_texts1:
    tx.set_size(10)
    tx.set_color("black")
    tx.set_weight("medium")
ラベル文字の設定

 Axesクラスのpieメソッドで返ってきた値lbl_texts1を使ってラベル文字を設定しています。ここでは、ラベルのフォントサイズを「10」に、色を「black」に、フォントウェイトを「medium」に設定しています。

 フォントウェイトについては、「0」から「1000」の数値か、「ultralight」、「light」、「normal」、「regular」、「book」、「medium」、「roman」、「semibold」、「demibold」、「demi」、「bold」、「heavy」、「extra bold」、「black」から選択することができます。

パーセント文字の設定

# パーセンテージを表示する。
for tx in pct_texts1:
    tx.set_size(10)
    tx.set_color("white")
    tx.set_weight("bold")
パーセント文字の設定

 Axesクラスのpieメソッドで返ってきた値pct_texts1を使ってパーセント文字を設定しています。ここでは、パーセント文字のフォントサイズを「10」に、色を「white」に、フォントウェイトを「bold」に設定しています。

凡例の表示

# 凡例を表示する。
ax.legend(patches1, dataframe1["Fruit"], title="Fruit", loc="center left", bbox_to_anchor=(.93, .45))
凡例の表示

 Axesクラスのpieメソッドで返ってきた値patches1を使って凡例を表示しています。ここでは、用意したデータをソートしたものが格納されているディクショナリ変数dataframe1の「Fruite」値を使って凡例の見出しを、キーワード引数titleを使って凡例のタイトルを「Fruit」に、キーワード引数locとbbox_to_anchorを使って凡例の「center left」部分が座標「0.93, 0.45」に配置されるように設定しています。

 なお、凡例の配置については、「best」、「upper right」、「upper left」、「lower left」、「lower right」、「right」、「center left」、「center right」、「lower center」、「upper center」、「center」から選択することができます。

ドーナツグラフ

 次に、ドーナツグラフの描き方を解説していきます。

ドーナツグラフ

 ここでは、前章のグラフをドーナツ化し、その内側に各フルーツの金額ベースの消費量を円グラフにしたものを描画します。

内側の円グラフ

グラフタイトルの変更

# Axesのタイトルと色を設定する。
ax.set_title("トロピカルフルーツの消費量\n(外側:重量ベース、内側:金額ベース)")
ax.set_facecolor("whitesmoke")

 描画するグラフに応じてグラフのタイトルを変更します。

データのソートと描画

# データを金額ベースの降順でソートする。
dataframe2 = dataframe.sort_values(by="Amount[Yen]", ascending=False)

# データを描画する。
patches2, lbl_texts2, pct_texts2 = ax.pie(
    dataframe2["Amount[Yen]"],
    colors=[plt.get_cmap("Set2").colors[dataframe1.index.get_loc(i)] for i in dataframe2.index],
    counterclock=False,
    startangle=90,
    pctdistance=.7,
    autopct="%.d%%",
    wedgeprops={"alpha": .8, "linewidth": 1, "edgecolor": "white"},
    shadow=True,
    radius=0.56)
データのソートと描画

 pandasパッケージのDataFrameクラスを使ってディクショナリ変数dataの「Amount[Yen]」値をキーに降順にソートを行います。そして、前章で作成した円グラフの内側にソートした結果を使ってもうひとつの円グラフを描画します。このとき、キーワード引数colorsには、外側の円グラフを描画したときの各要素に使用した色と同じ色が内側の円グラフの各要素でも使用されるよう値を設定しています。また、キーワード引数radiusを使って内側の円グラフの半径を「0.56」に設定します。キーワード引数radiusは、円の中心が0で外側の円グラフの円周上が1となる値です。

パーセント文字の設定

# パーセンテージを表示する。
for tx in pct_texts2:
    tx.set_size(10)
    tx.set_color("white")
    tx.set_weight("bold")
パーセント文字の設定

 Axesクラスのpieメソッドで返ってきた値pct_texts2を使ってパーセント文字を設定しています。ここでは、パーセント文字のフォントサイズを「10」に、色を「white」に、フォントウェイトを「bold」に設定しています。

外側の円グラフ

# データを描画する。
patches1, lbl_texts1, pct_texts1 = ax.pie(
    dataframe1["Amount[kg]"],
    labels=dataframe1["Fruit"],
    colors=plt.get_cmap("Set2").colors,
    counterclock=False,
    startangle=90,
    autopct="%.d%%",
    pctdistance=.8,
    labeldistance=1.15,
    wedgeprops={"alpha": .8, "linewidth": 1, "edgecolor": "white", "width": .4},
    shadow=True,
    explode=(0, .04, 0, 0, 0))
外側の円グラフ

 外側の円グラフと内側の円グラフが重ならないように調整します。ここでは、キーワード引数wedgepropsを使って外側の円グラフの幅を「0.4」に設定します。

 これで、各フルーツの重量ベースの消費量を円グラフにしたものをドーナツグラフ化し、その内側に各フルーツの金額ベースの消費量を円グラフにしたものを描画できました。


以上、「Python初心者でも簡単!matplotlibを使った円グラフとドーナツグラフの描き方を徹底解説」でした。


この記事を書いた人

プロフィール

 その日暮らし

 こんにちは、その日暮らしです/地方国立大理系院卒→大手大企業就職→ソフト開発二十年超→メンタル壊して退職→ちょっと回復→資格取得頑張る(簿記3級と応用情報は合格でデスペはギブアップ)→コロナ禍で再就職無理→離婚orz→実家へ出戻ってこどおじ化(笑)→WordPressの勉強のためブログに挑戦/そんな訳でブログは始めたばかりですが日々いろんなことを試して得た知識を投稿していこうと思ってます/以上