Pynote

Python、機械学習、画像処理について

matplotlib - 2次元ヒストグラムを作成する方法について

関連

Axes.hist2d(x, y, bins=10, range=None, normed=False, weights=None,
            cmin=None, cmax=None, *, data=None, **kwargs)

基本的な使い方

データを作成する。

import matplotlib.pyplot as plt
import numpy as np
from numpy.random import multivariate_normal

# データを作成する。
x, y = np.random.multivariate_normal(
    [0, 0], [[1, 0], [0, 1]], size=100000).T
print(x.shape, y.shape)  # (100000,) (100000,)

x, y にデータを指定する。

fig, ax = plt.subplots(figsize=(6, 6))
ax.hist2d(x, y)

plt.show()


ビンを指定する。

bins にビンを指定できる。
作成されたビンの端点は返り値の xedges, yedges で取得できる。

bins=ビンの数

x 方向、y 方向を共に bins 等分してビンを作成する。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, bins=10)

# bins を描画する。
ax.set_xticks(xedges)
ax.set_yticks(yedges)
ax.grid()

plt.show()


bins=[xbins, ybins]

x 方向を xbins 等分、y 方向を ybins 等分して、ビンを作成する。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, bins=[8, 10])

# bins を描画する。
ax.set_xticks(xedges)
ax.set_yticks(yedges)
ax.grid()

plt.show()


bins=[v0, v1, ..., vn]

x 方向、y 方向を共に [v0, v1, ..., vn] で分割してビンを作成する。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, bins=np.linspace(-5, 5, 11))

# bins を描画する。
ax.set_xticks(xedges)
ax.set_yticks(yedges)
ax.grid()

plt.show()


bins=[[x0, x1, ..., xn], [y0, y1, ..., yn]]

x 方向を [x0, x1, ..., xn]、y 方向を [y0, y1, ..., yn] で分割して、ビンを作成する。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(
    x, y, bins=[np.linspace(-5, 5, 11), np.linspace(-8, 8, 17)])

# bins を描画する。
ax.set_xticks(xedges)
ax.set_yticks(yedges)
ax.grid()

plt.show()


ビンを作成する範囲を指定する。

デフォルトでは全データが収まる範囲 range=[[xmin, xmax], [ymin, ymax]] でビンが作成されるが、range でこの範囲を明示的に指定できる。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, range=[[-2, 2], [-2, 2]])

# bins を描画する。
ax.set_xticks(xedges)
ax.set_yticks(yedges)
ax.grid()

plt.show()


ヒストグラムを正規化する。

normed=True とするとヒストグラムが正規化されるが、これはヒストグラムの和を1とするのではなく、ヒストグラム確率密度関数と解釈して、積分した値が1となるように正規化することを意味するので注意する。
この仕様は内部で使用している numpy.histogram2d に由来する。

もし、総和が1になるように正規化したい場合は、weights 引数で各サンプルの重みを 1 / 全データ数 としてヒストグラムを計算する。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, bins=10, normed=True)

# ヒストグラムを確率密度関数と解釈して、積分した値が1となるように正規化する。
ws = xedges[1:] - xedges[:-1]
hs = yedges[1:] - yedges[:-1]
print(np.sum(ws * hs * h))  # 1.0

# ヒストグラムの総和を1にしたい場合は weights で調整する。
h, xedges, yedges, img = ax.hist2d(x, y, bins=10, weights=np.ones_like(x) / len(x))
print(h.sum())  # 1.000000000000015

頻度値が指定した未満のビンは非表示にする。

cmin で頻度値が指定した未満のビンは非表示にできる。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, bins=10, cmin=10)

plt.show()


カラーマップを指定する。

cmap でカラーマップを指定できる。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, cmap='magma')

plt.show()

vmin, vmax を指定すると、値を [vmin, vmax] の範囲でクリップした上で、[vmin, vmax] をカラーマップの [0, 1] に対応させる。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, vmin=0, vmax=1000)

plt.show()

norm で値をカラーマップの色に変換する際の関数を指定できる。

import matplotlib.colors as mcolors

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, norm=mcolors.PowerNorm(0.5))

plt.show()

透過度を設定する。

alpha で透過度を設定できる。

fig, ax = plt.subplots(figsize=(6, 6))
h, xedges, yedges, img = ax.hist2d(x, y, alpha=0.8)

plt.show()