matplotlibで3Dグラフを描画する

準備

データ処理用にnumpy、プロット用にpyplot、3次元なのでmpl_toolkits.mplot3dをインポートします。

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

描画するデータの作成

3次元で描画するにはメッシュ(2次元の網目)を作成するために2次元の配列を用意する必要があります。
まずarangeメソッドでx,yそれぞれを1次元領域で分割します。

x = np.arange(-3, 3, 0.25)
y = np.arange(-3, 3, 0.25)

2次元メッシュを作成するにはmeshgridメソッドを利用します。この関数の戻り値はX,Yに対応する行列で、Xは行にxの配列を、Yは列にyの配列を入れたものになっています。

X, Y = np.meshgrid(x, y)
print "x=" , x
print "X=" , X
print "y=" , y
print "Y=" , Y


x= [-3. -2. -1. 0. 1. 2.]
X= [ [-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.] ]
y= [-1. 0. 1. 2. 3.]
Y= [ [-1. -1. -1. -1. -1. -1.]
[ 0. 0. 0. 0. 0. 0.]
[ 1. 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2. 2.]
[ 3. 3. 3. 3. 3. 3.] ]

このXYを直接利用してzを計算します。計算結果も2次元配列になります。

x = np.arange(-3, 3, 0.25)
y = np.arange(-3, 3, 0.25)
X, Y = np.meshgrid(x, y)
Z = np.sin(X)+ np.cos(Y)


Z= [[ 0.3991823 -0.36899512 -0.30116868 0.54030231 1.38177329 1.44959973]
[ 0.85887999 0.09070257 0.15852902 1. 1.84147098 1.90929743]
[ 0.3991823 -0.36899512 -0.30116868 0.54030231 1.38177329 1.44959973]
[-0.55726684 -1.32544426 -1.25761782 -0.41614684 0.42532415 0.49315059]
[-1.1311125 -1.89928992 -1.83146348 -0.9899925 -0.14852151 -0.08069507]]

グラフの作成

figureメソッドでまず2次元の図を生成します。そのあとAxes3D関数で3次元版に変換します。
あとは、予め計算させておいた3次元の点列X,Y,Zをplotなどの3次元プロット関数に渡せばOKです。

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z)

ここまでの処理をまとめると下のようになります。

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

x = np.arange(-3, 3, 0.25)
y = np.arange(-3, 3, 0.25)
X, Y = np.meshgrid(x, y)
Z = np.sin(X)+ np.cos(Y)

fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z) #<---ここでplot

plt.show()


plot_wireframe以外にもいくつか関数が用意されていて様々な図を描くことができます。

ワイヤーフレーム

ax.plot_wireframe(X,Y,Z)

サーフェス

ax.plot_surface(X, Y, Z, rstride=1, cstride=1)

3次元プロット

plot3Dは単に与えられた1次元配列を3次元プロットする関数です。X,Y,Zは2次元配列なので、numpy.ravel関数で2次元配列を1次元配列に変換してから引数として渡します。図を描くと全て直線でつながっていることが分かります。

ax.plot3D(np.ravel(X),np.ravel(Y),np.ravel(Z))

等高線

contourf3Dは同じ高さを同じ色で塗りつぶす関数です。

ax.contour3D(X,Y,Z)
ax.contourf3D(X,Y,Z)


散布図

直線ではなくて点を3次元上にプロットするメソッドです。こちらも一旦1次元配列に変換してから引数に渡します。

ax.scatter3D(np.ravel(X),np.ravel(Y),np.ravel(Z))