1.

Matplotlib 線グラフ完全ガイド(plot / subplots / 軸 / fill_between)

編集
この記事の要点
  • 最も基本の API: plt.plot(x, y)。x を省略すれば 0, 1, 2, ... が使われる
  • 複数系列は plot を複数回呼ぶか、まとめて plt.plot(x, y1, x, y2, ...)
  • subplots で複数グラフを並べる: fig, axes = plt.subplots(2, 2)
  • 軸: xlim / ylim で範囲、yscale="log" で対数軸、twinx() で二軸
  • 装飾: grid(補助線)/ fill_between(塗りつぶし)/ 移動平均

最も簡単な線グラフ

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.plot(x, y)
plt.show()

x を省略すると x = [0, 1, 2, ..., len(y)-1] になります:

plt.plot([1, 4, 9, 16, 25])   # x = [0, 1, 2, 3, 4]
plt.show()

2 系統の API: pyplot と Object-Oriented

Matplotlib には書き方が 2 通りあります。コードが大きくなったら OO 派へ:

# pyplot 派 (MATLAB ライク, 短い)
plt.figure(figsize=(8, 4))
plt.plot(x, y)
plt.xlabel('x')
plt.title('Sin curve')
plt.show()

# Object-Oriented 派 (推奨, 複数グラフで分かりやすい)
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(x, y)
ax.set_xlabel('x')
ax.set_title('Sin curve')
fig.tight_layout()
fig.savefig('out.png', dpi=150)
plt.show()

複数系列を 1 つのグラフに

x = np.linspace(0, 2*np.pi, 100)

fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label='sin(x)', linestyle='-')
ax.plot(x, np.cos(x), label='cos(x)', linestyle='--')
ax.plot(x, np.tan(x), label='tan(x)', linestyle=':')
ax.set_ylim(-2, 2)        # tan が発散するので制限
ax.legend()
ax.grid(True)
plt.show()

subplots: 複数グラフを並べる

# 2x2 のグリッド
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('sin')

axes[0, 1].plot(x, np.cos(x), color='red')
axes[0, 1].set_title('cos')

axes[1, 0].plot(x, x**2)
axes[1, 0].set_title('x^2')

axes[1, 1].plot(x, np.exp(x/3))
axes[1, 1].set_yscale('log')
axes[1, 1].set_title('exp (log scale)')

fig.suptitle('Subplots Example', fontsize=16)
plt.tight_layout()
plt.show()
記法説明
plt.subplots()1 つ。fig, ax を返す
plt.subplots(2, 3)2 行 3 列。axes は 2D ndarray
plt.subplots(1, 3)1 行 3 列。axes は 1D ndarray
plt.subplots(2, 2, sharex=True)x 軸共有
plt.subplots(2, 2, sharey=True)y 軸共有
plt.subplot_mosaic('AB;CC')不均等レイアウト

軸の操作

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

# 範囲
ax.set_xlim(0, 10)
ax.set_ylim(-1.5, 1.5)

# 目盛
ax.set_xticks([0, 2, 4, 6, 8, 10])
ax.set_xticklabels(['Z', 'A', 'B', 'C', 'D', 'E'])

# 対数軸
ax.set_yscale('log')   # 'linear' / 'log' / 'symlog' / 'logit'

# 軸ラベル / タイトル
ax.set_xlabel('Time [s]')
ax.set_ylabel('Voltage [V]')
ax.set_title('Response Curve')

# 反転
ax.invert_yaxis()

# 軸の枠を消す
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

グリッド

ax.grid(True)                                        # 全グリッド
ax.grid(True, axis='x')                              # 縦線のみ
ax.grid(True, which='major', linewidth=1.0)          # 主目盛
ax.grid(True, which='minor', linewidth=0.3, alpha=0.5)  # 副目盛

# 副目盛を表示
ax.minorticks_on()

二軸グラフ (twinx)

fig, ax1 = plt.subplots()

# 左軸
ax1.plot(x, np.sin(x), color='blue', label='sin')
ax1.set_xlabel('x')
ax1.set_ylabel('sin(x)', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')

# 右軸を追加
ax2 = ax1.twinx()
ax2.plot(x, np.exp(x), color='red', label='exp')
ax2.set_ylabel('exp(x)', color='red')
ax2.tick_params(axis='y', labelcolor='red')

# 凡例統合
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')

plt.show()

fill_between で塗りつぶし

x = np.linspace(0, 10, 100)
y_mean = np.sin(x)
y_lower = y_mean - 0.3
y_upper = y_mean + 0.3

fig, ax = plt.subplots()
ax.plot(x, y_mean, label='平均', color='blue')

# 信頼区間っぽい塗りつぶし
ax.fill_between(x, y_lower, y_upper, alpha=0.3, color='blue', label='±0.3')

# y=0 との差を塗る
ax.fill_between(x, 0, y_mean, where=(y_mean >= 0), color='lightblue', alpha=0.5)
ax.fill_between(x, 0, y_mean, where=(y_mean <  0), color='lightcoral', alpha=0.5)

ax.legend()
plt.show()

移動平均と原系列の重ね合わせ

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
t = np.arange(200)
noisy = np.sin(t * 0.05) + np.random.normal(0, 0.3, 200)

# 移動平均(NumPy convolve)
window = 10
ma = np.convolve(noisy, np.ones(window) / window, mode='valid')

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(t, noisy, label='原系列', alpha=0.4)
ax.plot(t[window-1:], ma, label=f'MA({window})', color='red', linewidth=2)
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()

pandas DataFrame からの直接プロット

import pandas as pd

# pandas の plot メソッド(内部で matplotlib 呼ぶ)
df = pd.DataFrame({
    'A': np.cumsum(np.random.randn(100)),
    'B': np.cumsum(np.random.randn(100)),
    'C': np.cumsum(np.random.randn(100)),
}, index=pd.date_range('2026-01-01', periods=100))

df.plot(figsize=(10, 4), grid=True, title='Cumulative Walks')
plt.show()

# 個別の系列
df['A'].plot()
df.plot(y=['A', 'B'])
df.plot(secondary_y='C')   # 右軸

Seaborn との使い分け

用途推奨
シンプルな X-Y 線matplotlib
カテゴリ別の集計線・信頼区間seaborn.lineplot
ファセット(条件別小グラフ)seaborn.relplot
論文・出版向けに細かく整形matplotlib
探索的データ分析(EDA)seaborn / pandas.plot
import seaborn as sns

# 集計と信頼区間を自動で出す
sns.lineplot(data=df, x='time', y='value', hue='category', errorbar='se')

保存と表示形式

fig.savefig('out.png', dpi=300, bbox_inches='tight')
fig.savefig('out.pdf')           # ベクタ
fig.savefig('out.svg')           # ベクタ
fig.savefig('out.png', transparent=True)   # 背景透過

# Jupyter で SVG レンダリング
from IPython.display import set_matplotlib_formats
set_matplotlib_formats('svg')

FAQ

Q: 図が表示されない
A: スクリプト実行時は plt.show() 必須。Jupyter なら %matplotlib inline でセル内に表示。

Q: 文字化けする
A: 日本語が含まれる場合、matplotlib_fontja をインストール + import するのが最短解。

Q: 線が重なって見にくい
A: alpha=0.5 で半透明、linewidth で太さ調整、または subplots で分割。

📸 参考画像

※ 旧バージョンから引き継いだ参考画像です。手順・図解の補助としてご覧ください。

参考画像

編集
Post Share
子ページ
  1. 線のラベル
  2. マーカー
  3. 線の種類
同階層のページ
  1. 線グラフ
  2. 棒グラフ
  3. 円グラフ
  4. 散布図
  5. タイトルと軸のラベル
  6. グリッド線

最近更新/作成されたページ