概要
matplotlibで作成した2次元ヒートマップをmatplotlibで3次元で表示する方法を紹介します。
また、番外編ですがPlotlyを使い、インタラクティブな3次元のグラフを作成する方法も紹介します。
Google Colabで作成したコードは、こちらにあります。
手順
- 各種インポートします。(各モジュールの実行時のversionは、Google Colab内で作成したコードにあります。)
- 2次元ヒートマップに使う2次元配列を用意します。
- 2次元配列をimshowを使い、2次元ヒートマップで表示します。
- matplotlibのAxes3Dを使い、3次元で表示します。
- (番外編)Plotlyを使い、matplotlibで作ったグラフをインタラクティブな3次元のグラフで表示します。
1. 各種インポート
各種インポート
import numpy as np
from matplotlib.image import imread
import matplotlib.pyplot as plt
import matplotlib.colors
from mpl_toolkits.mplot3d import Axes3D
import plotly.graph_objects as go
各モジュールの実行時のversionは、Google Colab内で作成したコードこちらにあります。
2. 2次元ヒートマップに使う2次元配列を用意
適当なサンプルの2次元配列を用意します。
サンプルとして使う、2次元ヒートマップ用の2次元配列
def func(x, y):
z = 0.01*(x*np.sin(0.1*x) + y*np.cos(0.1*y))
return z
y_shape, x_shape = (50, 100)
image = np.empty((y_shape, x_shape))
for y in range(y_shape):
for x in range(x_shape):
image[y][x] = func(x, y)
3. matplotlibのimshowを使い、2次元ヒートマップで表示
2次元ヒートマップで表示
fig = plt.figure(figsize=(8, 4))
ax = fig.add_subplot(111)
color = ax.imshow(image, cmap='CMRmap', origin='lower')
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.colorbar(color, shrink=0.8, label='z')
plt.show()
4. matplotlibのAxes3Dで3次元で表示
x軸とy軸の縮尺を統一するために、共通の軸の範囲ax.set_xlim(0, np.max(image.shape))
、
ax.set_ylim(0, np.max(image.shape))
を使います。
2次元ヒートマップを3次元で表示
fig = plt.figure(figsize=(13, 10))
ax = fig.add_subplot(111, projection='3d')
# 格子点を生成
y, x = np.mgrid[:image.shape[0], :image.shape[1]]
color = ax.plot_surface(x, y, image, cmap='CMRmap',
edgecolor='k', rstride=5, cstride=5)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_xlim(0, np.max(image.shape))
ax.set_ylim(0, np.max(image.shape))
cbar = plt.colorbar(color, shrink=0.6, label='z')
plt.show()
角度を変えたい場合
ax.view_init()を使うと、任意の角度で表示できます。
fig = plt.figure(figsize=(13, 10))
# 3Dプロット
ax = fig.add_subplot(111, projection='3d')
y, x = np.mgrid[:image.shape[0], :image.shape[1]]
color = ax.plot_surface(x, y, image, cmap='CMRmap',
edgecolor='k', rstride=5, cstride=5)
ax.view_init(80, 270) # 表示角度の追加, ax.view_init(縦方向の角度, 横方向の角度)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.set_xlim(0, np.max(image.shape))
ax.set_ylim(0, np.max(image.shape))
cbar = plt.colorbar(color, shrink=0.6, label='z')
plt.show()
5. (番外編)Plotlyを使い、matplotlibで作ったグラフをインタラクティブな3次元のグラフで表示
Plotlyを使い、インタラクティブな3次元で表示
fig = go.Figure(go.Surface(
x=np.arange(image.shape[1]),
y=np.arange(image.shape[0]),
z=image,
opacity=1.0, # 透明度(透明0-1不透明)
colorbar=dict(title='z') # colorbarのタイトル
))
fig.update_layout(
scene=dict(
xaxis=dict(nticks=10, range=[0,np.max(image.shape)],), # x軸の範囲
yaxis=dict(nticks=10, range=[0,np.max(image.shape)],), # y軸の範囲
),
width=700, # インライン表示の横幅のエリア
height=700, # インライン表示の縦幅のエリア
margin=dict(l=50, r=50, b=50, t=50)
)
# 等高線の表示
'''パラメータ
show : グラフと面に常に等高線を表示するか
usecolormap : 等高線にカラーマップの色を表示するか
highlightcolor : colorの色
project_z : 面に等高線を投影するか
'''
fig.update_traces(contours_z=dict(show=True, usecolormap=True,
highlightcolor='limegreen',
project_z=True
))
fig.show()
Google Colab内でもインタラクティブに動きます。
まとめ
matplotlibで作成した2次元ヒートマップを3次元で表示する方法を紹介しましたが、2次元ヒートマップの良さもあるので、状況によって使い分けましょう。
3次元は角度によって見えない領域があるので、番外編で紹介したPlotlyが3次元を表示するのに便利です。