Pynote

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

matplotlib - contour() で等高線を描画する。

概要

contour() で等高線を描画する際の各種設定について紹介する。

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

pynote.hatenablog.com

基本的な使い方

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

まず np.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.contour(X, Y, Z) と渡す。
等高線グラフは QuadContourSet オブジェクトで構成される。
contour() は返り値として Axes に追加したこのオブジェクトを返す。

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

# 等高線を作成する。
ax1 = fig.add_subplot(121)
ax1.set_title('contour')
contour = ax1.contour(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.contour(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.contour(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.contour(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.contour(X, Y, Z, levels=5, cmap='magma')
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.contour(X, Y, Z, alpha=0.8)
plt.show()


線の太さを指定する。

linewidths 引数で線の太さを指定できる。

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.contour(X, Y, Z, linestyles='dashed')
plt.show()


線の種類を指定する。

linestyles 引数で線の種類を指定できる。

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.contour(X, Y, Z, linestyles='dashed')
plt.show()