Pynote

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

matplotlib - contourf で塗りつぶした等高線を描画する方法

概要

contourf() で塗りつぶした等高線を描画する方法について紹介する。

contourf() は塗りつぶした等高線を作成するので、等高線のみ作成する場合は contour() 関数を使用する。

基本的な使い方

Axes.contourf([X, Y,] Z, [levels], **kwargs)

まず numpy.mgrid で格子状の点を作成し、この各点における関数の値を計算する。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2 + x * y


X, Y = np.mgrid[-3:3, -3:3]
print("X:\n", X)
print("Y:\n", Y)

Z = f(X, Y)
print("Z:\n", Z)
X:
 [[-3 -3 -3 -3 -3 -3]
 [-2 -2 -2 -2 -2 -2]
 [-1 -1 -1 -1 -1 -1]
 [ 0  0  0  0  0  0]
 [ 1  1  1  1  1  1]
 [ 2  2  2  2  2  2]]
Y:
 [[-3 -2 -1  0  1  2]
 [-3 -2 -1  0  1  2]
 [-3 -2 -1  0  1  2]
 [-3 -2 -1  0  1  2]
 [-3 -2 -1  0  1  2]
 [-3 -2 -1  0  1  2]]
Z:
 [[27 19 13  9  7  7]
 [19 12  7  4  3  4]
 [13  7  3  1  1  3]
 [ 9  4  1  0  1  4]
 [ 7  3  1  1  3  7]
 [ 7  4  3  4  7 12]]

Axes 上に 3D グラフを追加するには、用意した X, Y, Z を Axes.contourf(X, Y, Z) と渡す。
等高線グラフは QuadContourSet オブジェクトで構成される。
contourf() は返り値として Axes に追加したこのオブジェクトを返す。

fig = plt.figure(figsize=(9, 4))

# 等高線を作成する。
ax1 = fig.add_subplot(121)
ax1.set_title("contour")
contour = ax1.contourf(X, Y, Z)
print(type(contour))  # <class 'matplotlib.contour.QuadContourSet'>

# 3D グラフを作成する。
ax2 = fig.add_subplot(122, projection="3d")
ax2.set_title("surface")
ax2.plot_surface(X, Y, Z)

plt.show()


等高線の間隔を指定する。

levels 引数で指定する。
整数を指定した場合は、描画範囲を levels 段階に分けるように等高線を作成する。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

# 描画範囲を10段階に分けるように等高線を作成する。
fig, ax = plt.subplots(figsize=(6, 6))
ax.contourf(X, Y, Z, levels=10)
plt.show()

リストを指定した場合、関数がその値をとる点を結ぶように等高線を作成する。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

# f(x, y) = 0, 10, 50, 100, 200 となる等高線を作成する。
fig, ax = plt.subplots(figsize=(6, 6))
ax.contourf(X, Y, Z, levels=[0, 10, 50, 100, 200])

plt.show()


色を指定する。

colors 引数で色を指定できる。
リストを指定した場合、内側から順に指定した色が使用される。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

# 色を個別に指定する。
fig, ax = plt.subplots(figsize=(6, 6))
ax.contourf(X, Y, Z, levels=5, colors=["red", "blue", "green", "pink", "yellow"])

plt.show()


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

cmap 引数で値に応じて色を変化させるカラーマップを設定できる。

連続的な値の変化に対応した Sequential カテゴリのカラーマップがおすすめ。

pynote.hatenablog.com

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

# カラーマップで指定する。
fig, ax = plt.subplots(figsize=(6, 6))
ax.contourf(X, Y, Z, levels=5, cmap="magma")

plt.show()


カラーバーを追加する。

contourf() の返り値 QuadContourSet を Figure.colorbar() に渡すことで、カラーバーを Axes に追加できる。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

fig, ax = plt.subplots(figsize=(8, 6))
contour = ax.contourf(X, Y, Z)
fig.colorbar(contour)

plt.show()


色を透過する。

alpha 引数に [0, 1] の範囲の浮動小数点数を指定することで透過度を設定できる。
デフォルトは 1.0 なので、透過なし。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


def f(x, y):
    return x ** 2 + y ** 2


X, Y = np.mgrid[-10:11, -10:11]
Z = f(X, Y)

fig, ax = plt.subplots(figsize=(6, 6))
ax.contourf(X, Y, Z, levels=5, alpha=0.8)

plt.show()