Matplotlibの注釈とテキスト: インサイトをはっきり示す
Updated on
ピークやバーにラベルがないと、読者は推測するしかありません。テキストが重なったりデータから離れるとメッセージが埋もれます。短いラベル、適切な矢印、統一されたフォントで視線を導くのが解決策です。
適切なテキスト手法を選ぶ
| 目的 | ツール | 理由 |
|---|---|---|
| 特定点を矢印で示す | annotate | テキストと矢印を1回で設定 |
| 軸座標で自由に配置 | text | タイトルやパネル内メモ |
| バーに自動ラベル | bar_label | ラベルをバーに固定 |
| ラベルを枠内に保持 | clip_on=True, オフセット | テキストのはみ出し防止 |
| テキスト折り返し/整形 | textwrap.fill, f-string | 短く読みやすいラベルを維持 |
ピークを矢印で注釈する
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 300)
y = np.sin(x) * np.exp(-x / 5)
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, y, color="tab:blue")
peak_idx = np.argmax(y)
peak_x, peak_y = x[peak_idx], y[peak_idx]
ax.annotate(
"ピーク",
xy=(peak_x, peak_y),
xytext=(peak_x + 1.2, peak_y + 0.2),
arrowprops=dict(arrowstyle="->", color="tab:red", lw=1.5),
bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="tab:red", alpha=0.9),
fontsize=10,
color="tab:red",
)
ax.set_xlabel("Time (s)")
ax.set_ylabel("Amplitude")
ax.grid(True, linestyle="--", alpha=0.3)
plt.tight_layout()
plt.show()ポイント:
xytextで少しずらし、矢印を短く読みやすく。- 背景ボックスで混雑したグラフでもコントラストを確保。
- 2〜4語程度に抑えてデータを隠さない。
バーを重ならずにラベル付け
import matplotlib.pyplot as plt
items = ["A", "B", "C", "D"]
values = [28, 35, 30, 22]
fig, ax = plt.subplots(figsize=(6, 4))
bars = ax.bar(items, values, color="tab:purple", alpha=0.9)
ax.bar_label(bars, labels=[f"{v}k" for v in values], padding=3)
ax.set_ylabel("Units sold")
ax.set_ylim(0, 40)
plt.tight_layout()
plt.show()ポイント:
paddingで距離を調整。負の値ならバー内に配置。- 積み上げバーは
label_type="center"で中央に配置。 - 小さな値は文字色を白にし、内側に置いてコントラストを確保。
インラインメモと安全な配置
ax.text(
0.02, 0.95, "Experiment 3\nn=120",
transform=ax.transAxes,
ha="left", va="top",
fontsize=9,
bbox=dict(boxstyle="round", fc="white", ec="0.7", alpha=0.8)
)ガイド:
transform=ax.transAxesなら0–1の位置がリサイズ後も維持される。clip_on=Trueでテキストが枠外に出るのを防ぐ。ha/vaで整列し、短い改行でエッジへの衝突を回避。
トラブルシュート
- ラベルが重なる? フォント縮小、
padding調整、軽く回転。 - 矢印が隠れる?
zorderを上げるか塗りつぶし後に描く。 - テキストが枠外?
constrained_layout=Trueを有効化、またはtextwrap.fillで短くする。