Matplotlib 軸・注釈・凡例の設定方法・見やすいグラフを作るコツ【第6回】

Colab Export

💡 Pandas DataFrame入門シリーズ

このページは「Pandas DataFrame入門」シリーズの続編です。Matplotlibを使ってデータを可視化する方法を解説します。

この記事は、Python を使ってデータ分析結果を分かりやすく伝えたいと考えている方、特に Matplotlib でグラフを作成する際に「どうすればもっと見やすくなるのだろう?」と感じている方を対象としています。同じデータでも、グラフの「軸・注釈・凡例」を少し整えるだけで、その印象は劇的に変わります。本記事では、Python の強力なグラフ描画ライブラリ Matplotlib を使って、見る人が一目で理解できる、プロフェッショナルなグラフを作成するための実践的なテクニックを徹底解説します。

Major/Minor 目盛りの設定から、数値フォーマット、注釈(annotate)の使い方、特定の領域の強調、そして凡例の最適な配置や装飾まで、コピペでそのまま使える豊富なコード例とともにご紹介します。

この記事を最後まで読めば、あなたのグラフ作成スキルが格段にアップし、データがより雄弁に語り始めるはずです!さあ、一緒に「伝わるグラフ」作りに挑戦しましょう!

この記事で学べること:Matplotlib グラフ作成の重要テクニック

この記事を読むことで、Matplotlib を使ったグラフ作成において、以下の重要なスキルを習得できます。

1. 軸ラベル・単位・目盛り:グラフの基本情報を正確に伝える設定方法 2. 数値フォーマット:桁区切り、パーセント、指数など、データを分かりやすく整形 3. 注釈(annotate):グラフの特定ポイントに解説を加えて理解を深める 4. 領域強調axvspan, axhspan で重要な範囲を視覚的にハイライト 5. 凡例:複数データを整理し、見やすい位置に配置・装飾するテクニック

これらのテクニックをマスターして、あなたのグラフを次のレベルへ引き上げましょう!

1. グラフの第一印象を決める:軸ラベルと単位を明確に設定しよう

グラフを見た人が最初に目を向けるのは、間違いなく軸です。ここに何がプロットされているのか、どんな単位で表されているのかを明確に示すことで、データの意味が一瞬で伝わります。

まずは、グラフの顔とも言える軸ラベルと単位の基本的な設定方法から見ていきましょう。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

2. 目盛りを調整して、グラフの精度と読みやすさを向上させる(Major/Minor ・間隔・向き)

目盛りは、グラフが示す数値の精度を伝える上で非常に重要です。Major 目盛りと Minor 目盛りを適切に使い分け、間隔や表示形式を調整することで、グラフの読みやすさを格段に向上させることができます。

MultipleLocatorは、何単位ごとにMajor目盛りを表示するかを設定します。また、AutoMinorLocatorは、Major目盛りの間に、Minor目盛りを自動で何本入れるかを決定します。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

# 目盛りの位置を制御する MultipleLocatorとAutoMinorLocatorをインポート
from matplotlib.ticker import MultipleLocator, AutoMinorLocator

# 1番目のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")


# x軸について、Major目盛りを1、Minor目盛りを2分割(1番目のコードと比較して、X軸のMajor目盛りの間隔が明確になり、Minor目盛りが追加されているのが分かります)
ax.xaxis.set_major_locator(MultipleLocator(1))
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
# y軸について、Major目盛りを5000刻み、Minor目盛りを5分割
ax.yaxis.set_major_locator(MultipleLocator(5000))
ax.yaxis.set_minor_locator(AutoMinorLocator(5))


# 目盛りの向きや長さ(1番目のコードと比較して、目盛りが外側に出て長さが変わっているのが分かります)
ax.tick_params(axis="x", which="major", direction="out", length=6)
ax.tick_params(axis="x", which="minor", direction="out", length=3)
ax.tick_params(axis="y", which="major", direction="out", length=6)
ax.tick_params(axis="y", which="minor", direction="out", length=3)


# ラベル回転 (ここでは回転しない設定ですが、必要に応じて角度を変更できます)
for label in ax.get_xticklabels():
    label.set_rotation(0)   # 反時計回りに0度, 30度, 45度回転 など
# ラベルの文字の中心が、対応する目盛り線(ティック)の位置にくるように調整されます。
    label.set_horizontalalignment("center")
# Y軸のラベルも調整(ラベルの文字の中央が、対応するY軸の目盛り線と一致するように配置)
for label in ax.get_yticklabels():
     label.set_verticalalignment("center")


plt.tight_layout()
plt.show()
figure

3. 数値フォーマットで、データの「意味」を正確に伝える(桁区切り・%)

グラフに表示される数値は、それが金額なのか、あるいは割合なのかによって、最適な表示形式が異なります。桁区切り、パーセント表示などを適切に使い分けることで、データの持つ意味をより正確に、そして直感的に伝えることが可能になります。

Matplotlib には、StrMethodFormatter, PercentFormatter, FuncFormatter など、目的に合わせた様々なフォーマッターが用意されています。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib


# StrMethodFormatter, PercentFormatterをインポート
from matplotlib.ticker import StrMethodFormatter, PercentFormatter

# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o") # 折れ線グラフで表示

# 桁区切り(12,000 形式)
ax.yaxis.set_major_formatter(StrMethodFormatter("{x:,.0f}"))

# %表示(0.0〜1.0を0〜100%として表示する場合の例)
# ax.yaxis.set_major_formatter(PercentFormatter(xmax=1.0, decimals=0))


ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

さらに、FuncFormatter を使えば、独自の関数を定義して、より自由度の高い数値フォーマットを実現できます。例えば、特定の通貨記号を付けたり、条件に応じて表示形式を切り替えたりといった、細やかなカスタマイズが可能です。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

# FuncFormatterをインポート
from matplotlib.ticker import FuncFormatter


# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

def yen(x, pos):
    return f"¥{x:,.0f}"

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.yaxis.set_major_formatter(FuncFormatter(yen))
ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上")
plt.tight_layout()
plt.show()
figure

4. 注釈と矢印で、グラフの「ここがポイント!」を明確に示す(annotate)

グラフの中で特に注目してほしいデータポイントや、重要なイベント発生箇所などを解説したい場合に絶大な効果を発揮するのが「注釈(annotate)」です。テキストと矢印を組み合わせることで、グラフ上の特定の要素を指し示し、補足説明を分かりやすく加えることができます。

arrowprops を設定すれば、矢印のスタイル、色、太さなども自由にカスタマイズでき、より表現力豊かな注釈を作成できます。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib


# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")

# リストyの中で最大値を持つ要素のインデックス(位置)を取得する。peak_idx=3
peak_idx = y.index(max(y))

# ピークの月に注釈を追加
ax.annotate("ピーク", xy=(x[peak_idx], y[peak_idx]), xytext=(x[peak_idx]+0.5, y[peak_idx]+5000), # xytextのY座標も調整
            arrowprops=dict(arrowstyle="wedge,tail_width=0.7", lw=1.5, fc="red", ec="red")) # 矢印スタイルを変更

ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

【コードの補足】

ax.annotate()関数は、グラフにテキストと矢印を追加します。主な引数は以下の通りです。

  • 最初の引数: グラフ上に表示される注釈テキスト(例: “ピーク”)。
  • xy: 矢印の先端が指すグラフ上のデータ座標。この例では売上ピークの月と売上額を指定。
  • xytext: 注釈テキストが配置される表示座標。ピークのデータポイントから少し右上にずらして配置しています。
  • arrowprops: 矢印のスタイルをカスタマイズする辞書。ここでは以下の設定をしています。
  • arrowstyle="wedge,tail_width=0.7": くさび形の矢印。
  • lw: 線幅。
  • fc: 塗りつぶし色。
  • ec: 縁の色。
  • これにより、赤色の強調された矢印を作成しています。

5. 領域強調で、特定の範囲や期間を視覚的にハイライトする(axvspan/axhspan)

グラフ上で特定の期間や数値の範囲を強調して見せたい場合に非常に便利なのが、axvspan (垂直方向の帯) と axhspan (水平方向の帯) です。これらの関数を使うと、グラフ上に簡単に色付きの帯状領域を描画し、特定の範囲を視覚的に際立たせることができます。

例えば、特定のキャンペーン期間や、目標値として設定した範囲を示す際などに効果的です。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib


# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y = [10000, 23000, 18000, 30000, 28000]

fig, ax = plt.subplots()
ax.plot(x, y, marker="o")

# x=2〜4の範囲(2ヶ月目から4ヶ月目)を薄く着色
ax.axvspan(2, 4, alpha=0.15, label="キャンペーン期間") # ラベルを追加
ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
ax.legend() # 凡例を表示
plt.tight_layout()
plt.show()
figure

6. 凡例を使いこなす:複数のデータ系列を分かりやすく整理する

複数のデータ系列を一つのグラフに重ねて表示する場合、凡例はグラフを理解するための羅針盤となります。どの線や棒がどのデータを表しているのかを明確に示すことで、グラフの解読をスムーズにします。

凡例はグラフ内に配置するだけでなく、グラフの外側に配置して描画領域を最大限に活用することも可能です。また、凡例の項目を複数列にしたり、枠線や背景色などの装飾を施したりすることで、さらに見やすく整理できます。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y1 = [10000, 23000, 18000, 30000, 28000]

# データを追加
y2 = [15000, 18000, 25000, 22000, 35000]

fig, ax = plt.subplots()
ax.plot(x, y1, marker="o", label="売上A")
ax.plot(x, y2, marker="o", label="売上B") # 追加データをプロット

# 外出し:右側中央
ax.legend(loc="center left", bbox_to_anchor=(1.02, 0.5), borderaxespad=0)


# 装飾(枠・角丸・透明度・タイトル)
leg = ax.get_legend()
leg.set_title("凡例")
leg.get_frame().set_alpha(0.9)   # 透明度
leg.get_frame().set_linewidth(0.8)

ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

【コードの補足:ax.legend()関数】

  • loc パラメータ: 設定値 center left
  • 凡例ボックス の アンカーポイント を、凡例自体の 左端の中央 に設定します。
  • bbox_to_anchor パラメータ: 設定値 (1.02, 0.5)
  • 凡例のアンカーポイントを、Axes (グラフ本体の描画領域) のどの座標に配置するかを指定します。
  • 1.02 (X座標): Axesの右端 (1.0) から Axes幅の2%分外側 (右側) を指定します。
  • 0.5 (Y座標): Axesの 垂直方向の中央 を指定します。
  • borderaxespad パラメータ: 設定値 0
  • 凡例がAxesの外側に配置される際、Axesとの間に設ける 余白 (パディング) を指定します。0は余白なしを意味します。

凡例の項目が多い場合にスペースを節約したいときは、グラフの下部中央に複数列で凡例を配置するのが効果的です。その例を見てみましょう。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

# 最初のコードと同じデータを使用。
x = [0, 1, 2, 3, 4]
y1 = [10000, 23000, 18000, 30000, 28000]
y2 = [15000, 18000, 25000, 22000, 35000]
y3 = [12000, 20000, 22000, 28000, 32000] # 3つ目のデータを追加

fig, ax = plt.subplots()
ax.plot(x, y1, marker="o", label="売上A")
ax.plot(x, y2, marker="o", label="売上B")
ax.plot(x, y3, marker="o", label="売上C") # 3つ目のデータをプロット

ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.15), ncol=3, frameon=True)

ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

【コードの補足:ax.legend()関数】

  • loc パラメータ: 設定値 upper center
  • 凡例ボックス の アンカーポイント を、凡例自体の 上端の中央 に設定します。
  • bbox_to_anchor パラメータ: 設定値 (0.5, -0.15)
  • 凡例のアンカーポイントを、Axes (グラフ本体の描画領域) のどの座標に配置するかを指定します。
  • 0.5 (X座標): Axesの 水平方向の中央 を指定します。
  • -0.15 (Y座標): Axesの下端 (0.0) から Axesの高さの15%分 外側 (下側) を指定します。
  • ncol パラメータ: 設定値 3
  • 凡例の項目を 3列 に並べて表示します。長い凡例をコンパクトにまとめるのに役立ちます。
  • frameon パラメータ: 設定値 True
  • 凡例の周囲に 枠線(フレーム)を表示します。

凡例に表示されるラベルは、通常 plot 関数などで指定した label 引数が自動的に使われます。しかし、Line2D オブジェクトなどを利用することで、凡例に表示する「ハンドル(線やマーカー)」と「ラベルテキスト」を後から自由に組み合わせて設定することも可能です。これにより、より柔軟な凡例のカスタマイズが可能になります。

import matplotlib.pyplot as plt

!pip install japanize-matplotlib > /dev/null # Google Colab の機能を使って日本語フォントをインストール・インポート
import japanize_matplotlib

# Line2Dをインポート
from matplotlib.lines import Line2D

# 最初のコードと同じデータを使用
x = [0, 1, 2, 3, 4]
y1 = [10000, 23000, 18000, 30000, 28000]
y2 = [15000, 18000, 25000, 22000, 35000]

fig, ax = plt.subplots()
# labelは指定せず、後でhandlesとlabelsで設定
l1, = ax.plot(x, y1, marker="o", color="C0")
l2, = ax.plot(x, y2, marker="o", color="C1")

# handlesとlabelsを個別に定義して凡例を作成
handles = [Line2D([0], [0], color="C0", marker="o"), # マーカーも表示
           Line2D([0], [0], color="C1", marker="o")]
labels = ["シリーズα", "シリーズβ"] # ラベルテキストを任意に設定
ax.legend(handles, labels, loc="best")

ax.set_title("売上の推移")
ax.set_xlabel("月")
ax.set_ylabel("売上(円)")
plt.tight_layout()
plt.show()
figure

7. これで解決!Matplotlib グラフ作成でよくある「困った!」と対策

Matplotlib でグラフを作成していると、「あれ?思った通りにならないな…」という場面に遭遇することは少なくありません。ここでは、多くの人が経験するであろう、よくある「ハマりどころ」とその効果的な解決策をまとめました。

  • 凡例をグラフの外に出したら、グラフの一部が切れてしまう: グラフをファイルに保存する際に、fig.savefig(..., bbox_inches="tight") を使うのが定番の解決策です。
  • 軸ラベルや目盛りのラベルが重なって読みにくい: まずは plt.tight_layout()fig.set_constrained_layout(True) を試してみましょう。それでも改善しない場合は、ラベルを回転させるか、図全体のサイズやレイアウトを調整する必要があります。
  • 意図せず数値が指数表記(科学表記)になってしまう: ScalarFormatter を使用し、set_powerlimits() で指数表記に切り替わる数値の範囲を細かく制御できます。
  • Minor 目盛りが表示されない: AutoMinorLocator などのロケーターを設定するだけでなく、ax.tick_params(which="minor", ...) で minor 目盛りの表示設定(長さや色など)も忘れずに行う必要があります。

まとめ:見やすいグラフ作成のための Matplotlib 重要テクニック集

この記事で解説した、Matplotlib を使って「伝わるグラフ」を作成するための重要な設定テクニックを最後におさらいしましょう。これらのポイントを押さえるだけで、あなたのグラフはより魅力的で、データが語りかけるメッセージが明確になるはずです!

  • 目盛りの調整: MultipleLocatorAutoMinorLocator で Major/Minor 目盛りの間隔を自在に設定し、tick_params で見た目を細かく調整。
  • 数値フォーマット: StrMethodFormatter, PercentFormatter, FuncFormatter を使い分け、金額や割合、科学的な値を最も分かりやすい形式で表示。
  • 注釈と強調: annotate でグラフのキーポイントに解説を加え、axvspan/axhspan で特定の範囲を視覚的にハイライト。
  • 凡例: loc, bbox_to_anchor, ncol で最適な配置とレイアウトを実現し、get_legend().get_frame() で装飾をカスタマイズ。

これらのテクニックをぜひあなたのグラフ作成ワークフローに取り入れてみてください。きっと、データ分析の結果をより効果的に伝えることができるようになるでしょう!

▲ ページトップへ戻る

コメント

タイトルとURLをコピーしました