3.

Matplotlib 円グラフ (pie chart) 完全ガイド

編集
この記事の要点
  • 基本は plt.pie(values, labels=labels, autopct="%1.1f%%")
  • explode で特定のスライスを切り出し強調、startangle=90 で開始位置調整
  • ドーナツチャートは wedgeprops={"width": 0.5} で実現可能
  • 凡例は plt.legend(loc="best")。要素が多いときは凡例側にラベルを寄せると見やすい
  • カテゴリが多い (7 以上) 場合は 横棒グラフ推奨。Seaborn には円グラフが意図的にない

最小例

import matplotlib.pyplot as plt

labels = ['Python', 'JavaScript', 'Java', 'C++', 'Go']
sizes  = [45, 25, 15, 10, 5]

plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
plt.axis('equal')   # 真円にする
plt.title('Language Share (sample)')
plt.show()

主なパラメータ

引数用途
labelsスライス外側のラベルlabels=['A','B']
autopctパーセント表示フォーマットautopct='%1.1f%%'
explode各スライスの引き離し量explode=[0,0.1,0,0,0]
colors色のリストcolors=['r','g','b']
startangle開始角 (反時計回り)startangle=90
counterclock反時計回りかcounterclock=False
shadow影を付けるshadow=True
wedgepropsスライスの描画属性{'edgecolor':'w','linewidth':2}
textpropsテキスト属性{'fontsize':12}
pctdistance%テキストの中心からの距離pctdistance=0.75
labeldistanceラベルの距離labeldistance=1.1

explode で強調

import matplotlib.pyplot as plt

labels = ['Sales', 'Marketing', 'Engineering', 'Support', 'Other']
sizes  = [350, 220, 480, 130, 70]
explode = [0, 0, 0.08, 0, 0]   # Engineering だけ切り出し

plt.pie(sizes,
        labels=labels,
        autopct='%1.1f%%',
        explode=explode,
        startangle=90,
        shadow=True,
        colors=['#4C72B0', '#DD8452', '#55A467', '#C44E52', '#8172B2'])
plt.axis('equal')
plt.title('Headcount by Department')
plt.show()

ドーナツチャート

真ん中をくり抜くにはスライスの幅を wedgeprops で指定します。

import matplotlib.pyplot as plt

labels = ['Direct', 'Search', 'Social', 'Referral']
sizes  = [40, 35, 15, 10]

fig, ax = plt.subplots(figsize=(6, 6))
ax.pie(sizes,
       labels=labels,
       autopct='%1.0f%%',
       startangle=90,
       wedgeprops={'width': 0.4, 'edgecolor': 'white', 'linewidth': 2})

# 中央にテキスト
ax.text(0, 0, 'Traffic\nMix', ha='center', va='center', fontsize=14, weight='bold')

ax.set_aspect('equal')
plt.show()

凡例を使う

カテゴリ名が長い場合や、円外のラベルが他のスライスと衝突する場合は、ラベルを消して legend で代用します。

import matplotlib.pyplot as plt

labels = ['Company-issued laptops',
          'BYOD',
          'Virtual desktop',
          'Mobile only',
          'Other']
sizes = [62, 18, 12, 5, 3]

fig, ax = plt.subplots(figsize=(7, 5))
wedges, texts, autotexts = ax.pie(
    sizes,
    autopct='%1.1f%%',
    startangle=90,
    textprops={'color': 'white'},
)

ax.legend(wedges, labels, title='Device', loc='center left',
          bbox_to_anchor=(1, 0, 0.5, 1))
ax.set_title('Endpoint Mix')
plt.tight_layout()
plt.show()

絶対値とパーセントを両方表示

import matplotlib.pyplot as plt

labels = ['A', 'B', 'C', 'D']
sizes  = [120, 80, 30, 50]
total = sum(sizes)

def fmt(p):
    n = int(round(p * total / 100.0))
    return f'{p:.1f}%\n({n})'

plt.pie(sizes, labels=labels, autopct=fmt, startangle=90)
plt.axis('equal')
plt.show()

カテゴリが多すぎる場合

円グラフは 5 〜 6 スライスを超えると急速に読みづらくなります。10 個を超えるなら、横棒グラフへの置き換えを強く推奨します。

import matplotlib.pyplot as plt

# ❌ 12 カテゴリの円グラフは比較困難
labels = list('ABCDEFGHIJKL')
sizes = [15, 14, 13, 12, 10, 9, 8, 7, 5, 4, 2, 1]

# ✅ 横棒グラフに置き換え
labels_sorted, sizes_sorted = zip(*sorted(zip(labels, sizes), key=lambda p: p[1]))
plt.barh(labels_sorted, sizes_sorted, color='steelblue')
plt.xlabel('Count')
plt.title('Recommended: horizontal bar')
plt.tight_layout()
plt.show()

Seaborn には円グラフがない理由

Seaborn (統計可視化ライブラリ) には pieplot がありません。これは作者の方針で、「人間は扇形の面積を正確に比較できない」という研究知見に基づきます。代替として bar / catplot を使うのが Seaborn の流儀です。

とはいえ、経営向けレポートやプレゼンでは円グラフが好まれる文化もあるため、Matplotlib では引き続き使用可能です。

plotly との比較

インタラクティブ性が必要なら plotly が便利です:

import plotly.express as px

df = px.data.tips()
fig = px.pie(df, names='day', values='total_bill', hole=0.4)
fig.show()
# ホバーで値表示、クリックでスライス非表示など
用途推奨
論文 / レポート (静的画像)Matplotlib
ダッシュボード / Web 表示plotly / Bokeh / Vega-Altair
カテゴリ別の集計込みSeaborn (pie ではなく bar)

FAQ

Q: 真円にならず楕円になる
A: plt.axis('equal') または ax.set_aspect('equal') を呼んでください。Figure のアスペクト比に依存します。

Q: 小さなスライスのラベルが重なる
A: (1) labeldistance を大きくする、(2) 凡例にラベルを移す、(3) 「Other」にまとめる、のいずれか。

Q: パーセントを内側に、ラベルを外側にしたい
A: autopct='%1.1f%%' + pctdistance=0.7 (内側) と labeldistance=1.1 (外側) を組み合わせ。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 線グラフ
  2. 棒グラフ
  3. 円グラフ
  4. 散布図
  5. タイトルと軸のラベル
  6. グリッド線