この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: 散布図
SEOタイトル: Matplotlib 散布図 (scatter) 完全ガイド|サイズ・色・グラデーション・3D まで

この記事の要点
  • Matplotlib の散布図plt.scatter(x, y) または ax.scatter(x, y) で描画。線で結ばない点群表現の基本
  • 点ごとにサイズ s=c=マーカー marker=透明度 alpha=を指定でき、4 次元情報を 1 つの図に詰め込める
  • 色を数値 + cmap= で指定するとカラーバー付きグラデーションが描ける(バブルチャート的活用)
  • 点が重なる大量データには hexbin / hist2d による密度可視化が有効
  • Seaborn の sns.scatterplot()カテゴリ列で自動色分け・凡例自動生成と便利。3D は mpl_toolkits.mplot3d で対応

散布図とは

散布図 (Scatter Plot) は、2 つの量的変数の関係を 点の位置で表現するグラフです。データ分析の最初の一歩として「2 変数の相関を眺める」用途で最頻出します。

Matplotlib で描いた散布図の例

最小コード

import matplotlib.pyplot as plt
import numpy as np

# サンプルデータ
rng = np.random.default_rng(0)
x = rng.normal(0, 1, 100)
y = 2 * x + rng.normal(0, 1, 100)

plt.scatter(x, y)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot')
plt.show()

主なパラメータ

引数意味
s点のサイズ (面積、ポイント^2)s=50 / s=values
c点の色 (文字列 / RGB / 数値配列)c='red' / c=z
cmapカラーマップ (c が数値のとき)cmap='viridis'
markerマーカー記号'o' 〇 / '^' △ / 's' □ / '*'
alpha透明度 (0=完全透明、1=不透明)alpha=0.5
edgecolors点の縁の色edgecolors='black'
linewidths縁の太さlinewidths=0.5
label凡例用ラベルlabel='Group A'

サイズと色で多次元を表現

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(1)
n = 200
x = rng.uniform(0, 10, n)
y = rng.uniform(0, 10, n)
size = rng.uniform(10, 200, n)      # 各点の大きさ
color = rng.uniform(0, 1, n)        # 各点の色 (連続値)

plt.figure(figsize=(7, 5))
plt.scatter(x, y, s=size, c=color, cmap='viridis', alpha=0.7, edgecolors='black')
plt.colorbar(label='Value')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter (size + color encoded)')
plt.show()

これで (x, y, サイズ, 色) の 4 軸を 1 つの図に詰め込めます。Hans Rosling 型のバブルチャート (国×GDP×人口×大陸) もこのパターン。

複数系列を重ねる

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(2)

plt.figure(figsize=(7, 5))
plt.scatter(rng.normal(0, 1, 50), rng.normal(0, 1, 50),
            c='tomato', marker='o', alpha=0.7, label='Group A')
plt.scatter(rng.normal(2, 1, 50), rng.normal(1, 1, 50),
            c='royalblue', marker='^', alpha=0.7, label='Group B')
plt.scatter(rng.normal(-1, 0.5, 50), rng.normal(-2, 0.5, 50),
            c='seagreen', marker='s', alpha=0.7, label='Group C')

plt.legend(loc='upper left')
plt.title('3 Groups')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(alpha=0.3)
plt.show()

マーカー一覧

記号形状記号形状
'.'小さい点'^'上向き三角
'o'○ 円'v'下向き三角
'x'× バツ'<' / '>'横三角
'+'+ プラス's'□ 四角
'*'★ 星'd' / 'D'菱形 (細/太)
'p'五角形'h' / 'H'六角形

大量データ: 密度散布図

数万〜数十万点を scatter でそのまま描くと、点が重なって真っ黒な塊になります。密度を見える化するには:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(3)
x = rng.normal(0, 1, 50000)
y = rng.normal(0, 1, 50000)

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 1. scatter (alpha 小)
axes[0].scatter(x, y, s=2, alpha=0.05)
axes[0].set_title('scatter (alpha=0.05)')

# 2. hexbin (六角ビン)
hb = axes[1].hexbin(x, y, gridsize=40, cmap='Blues')
fig.colorbar(hb, ax=axes[1])
axes[1].set_title('hexbin')

# 3. hist2d (矩形ビン)
h = axes[2].hist2d(x, y, bins=40, cmap='Greens')
fig.colorbar(h[3], ax=axes[2])
axes[2].set_title('hist2d')

plt.tight_layout()
plt.show()

回帰直線・近似曲線の重ね描き

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(4)
x = rng.uniform(0, 10, 80)
y = 2.5 * x + 3 + rng.normal(0, 4, 80)

# 1 次回帰
a, b = np.polyfit(x, y, 1)
xs = np.linspace(0, 10, 100)
ys = a * xs + b

plt.scatter(x, y, alpha=0.6, label='Data')
plt.plot(xs, ys, color='red', label=f'y = {a:.2f}x + {b:.2f}')
plt.legend()
plt.title('Scatter with regression line')
plt.show()

Seaborn での散布図

カテゴリ別の色分けや回帰線の重ね描きは Seaborn が圧倒的に簡潔です。

import seaborn as sns
import matplotlib.pyplot as plt

iris = sns.load_dataset('iris')

# 種類で色分け
sns.scatterplot(data=iris, x='sepal_length', y='petal_length',
                hue='species', style='species', size='petal_width',
                sizes=(20, 200), alpha=0.7)
plt.title('Iris Scatter')
plt.show()

# 回帰線付き
sns.lmplot(data=iris, x='sepal_length', y='petal_length',
           hue='species', height=5, aspect=1.2)
plt.show()

# ペアプロット (全列の散布図行列)
sns.pairplot(iris, hue='species', diag_kind='kde')
plt.show()

3D 散布図

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401

rng = np.random.default_rng(5)
x = rng.normal(0, 1, 200)
y = rng.normal(0, 1, 200)
z = rng.normal(0, 1, 200)
c = x + y + z

fig = plt.figure(figsize=(7, 6))
ax = fig.add_subplot(111, projection='3d')
sc = ax.scatter(x, y, z, c=c, cmap='plasma', s=30)
fig.colorbar(sc, label='x+y+z')
ax.set_xlabel('X'); ax.set_ylabel('Y'); ax.set_zlabel('Z')
ax.set_title('3D Scatter')
plt.show()

カラーマップ早見

分類用途
Sequential (連続)viridis / plasma / Blues / Greens0 → 大 へ滑らかに変化する値
Diverging (発散)RdBu / coolwarm / PiYG0 を中心に正負へ広がる値
Qualitative (定性)tab10 / Set1 / Pairedカテゴリ (連続性なし)
Cyclic (循環)twilight / hsv角度・時刻・位相

色覚多様性 (色弱) への配慮として viridis 系が推奨されます (古典の jet は非推奨)。

FAQ

Q: plt.plot(x, y, 'o') でも散布図が描けますが scatter と何が違いますか?
A: plot全点で同じサイズ・色scatter点ごとに s/c を変えられるのが本質的違いです。少量で同色なら plot の方が速い場合あります。

Q: 点を見えないほどに重ねたい (heatmap 化)
A: alpha=0.05 程度を試し、それでも見にくければ hexbin / hist2d または seaborn.kdeplot() による密度推定をどうぞ。

Q: ラベル (テキスト) を点ごとに付けたい
A: ループで plt.annotate(label, (x, y)) を呼びます。点が密集している場合は adjustText ライブラリで自動回避できます。

Q: log スケールにしたい
A: plt.xscale('log') / plt.yscale('log')。指数的に広がるデータ (PV数 / 売上 等) で必須です。