検出力曲線

2標本 t 検定の検出力を、小・中・大の効果量ごとに標本サイズに対して描きます。

検出力曲線

統計的検出力とは、実際に存在する効果を研究が検出できる確率です。各曲線は、コーエンの基準となる効果量(小 d = 0.2、中 0.5、大 0.8)のそれぞれについて、群あたりの参加者数とともに検出力がどう増加するかを示しています。曲線が慣例的な 80% の線を横切る位置に、必要な標本サイズを点で示しています。効果が小さくなるにつれて、必要な標本サイズが急激に膨れ上がることに注目してください(x軸は対数軸です)。

statsmodels.stats.power.TTestIndPower で計算しています。曲線には .power() を、必要な n には .solve_power() を用いています(両側 α = .05、群のサイズは等しいと仮定)。

コードおよび図中のテキストは英語です。

power-curve.py · 45 行
ダウンロード GitHub
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FixedLocator, NullLocator
from statsmodels.stats.power import TTestIndPower

analysis = TTestIndPower()
n = np.geomspace(4, 1000, 300)  # participants per group
effects = {0.2: ("small", "#FF3B30"), 0.5: ("medium", "#FF9500"), 0.8: ("large", "#007AFF")}

fig, ax = plt.subplots(figsize=(8, 5))
ax.axhline(0.8, color="#8E8E93", ls="--", lw=1)
ax.text(1000, 0.815, "80% power", ha="right", va="bottom", fontsize=9, color="#6E6E73")

required = {}
for d, (name, c) in effects.items():
    power = analysis.power(effect_size=d, nobs1=n, alpha=0.05)
    power = np.nan_to_num(power, nan=1.0)  # the noncentral t returns NaN once power ≈ 1
    ax.plot(n, power, color=c, lw=2.2,
            label=f"d = {d} ({name})")
    # Sample size per group that reaches 80% power
    n80 = int(np.ceil(analysis.solve_power(effect_size=d, power=0.8, alpha=0.05)))
    required[d] = n80
    ax.vlines(n80, 0, 0.8, color=c, lw=1, ls=":")
    ax.scatter(n80, 0.8, s=60, color=c, edgecolor="white", lw=1.5, zorder=4)
    ax.annotate(f"n = {n80}\nper group", (n80, 0.8), xytext=(6, -8), textcoords="offset points",
                ha="left", va="top", fontsize=9, color=c, fontweight="semibold")

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], loc="upper left", title="Effect size (Cohen's d)",
          alignment="left", frameon=True, facecolor="white", edgecolor="none", framealpha=1)
ax.set_xscale("log")
ax.xaxis.set_major_locator(FixedLocator([5, 10, 20, 50, 100, 200, 500, 1000]))
ax.xaxis.set_minor_locator(NullLocator())
ax.xaxis.set_major_formatter(lambda v, _: f"{v:g}")
ax.set_xlim(4, 1000)
ax.set_ylim(0, 1.02)
ax.yaxis.set_major_formatter(lambda v, _: f"{v:.0%}")
ax.grid(axis="x")
ax.set_xlabel("Sample size per group (log scale)")
ax.set_ylabel("Power (1 − β)")
ax.set_title("Small effects need about 400 participants per group", pad=26)
ax.text(0, 1.02, "Two-sample t-test, two-sided α = .05, equal groups · n for 80% power: "
        + ", ".join(f"d = {d}: {k}" for d, k in required.items()),
        transform=ax.transAxes, fontsize=9.5, color="#6E6E73")
plt.show()

図にはオプションの PyStatlas スタイル を使用しています。同じ見た目にするには plt.style.use("pystatlas.mplstyle") を追加してください。

引用方法

PyStatlas は Thierry Warin が作成・運営しています。研究や業務に役立った場合は、ぜひ引用してください。

Warin, T. (2026). Power curve. In PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences. https://warint.github.io/pystatlas/inference-uncertainty/power-curve/

@misc{warin2026statlas,
  author       = {Warin, Thierry},
  title        = {PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences},
  year         = {2026},
  howpublished = {\url{https://warint.github.io/pystatlas/}},
  note         = {Source code: https://github.com/warint/pystatlas}
}

推測と不確実性のその他のグラフ