'20/08/10更新:記事とコードを若干編集しました。
本記事では、2つの方法について雛形コードを載せました。
■1. numpyのndarray型の「二重配列」でデータセットしてグラフ化する方法
二変数関数について、等高線図と三次元図を描画した例が下図5つです。





■2. numpyのndarray型の「一次元配列」でデータセットしてグラフ化する方法
ローレンツ方程式(常微分方程式)を三次元描画した例が下図3つです。



■本プログラム
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import seaborn as sns
import datetime
now = datetime.datetime.now()
now = now.strftime("%y%m%d")
def my_funcA(x, y):
return 6 * x - pow(x, 2) + 4 * y - pow(y, 2)
def my_funcB(x, y):
return pow(x, 2) - pow(y, 2)
def my_funcC(x, y):
return x*(np.exp(-1 * pow(x/5, 2) - pow(y/5, 2)))
def my_funcD(x, y):
return np.sin(x/2) + np.sin(y/2)
def my_funcE(x, y):
return np.cos(pow(x/5, 2) + pow(y/5, 2))
def my_lorenz(x, y, z, a=10, b=8/3, u=1):
x_dot = -a * x + a * y
y_dot = u * x - y - x * z
z_dot = -b * z + x * y
return x_dot, y_dot, z_dot
def my_contur_and_3Dgraph(X, Y, Z, function_name):
print('X -> ' + str(X) + '\n' + str(type(X)))
print('Y -> ' + str(Y) + '\n' + str(type(Y)))
print('Z -> ' + str(Z) + '\n' + str(type(Z)))
fig = plt.figure(figsize=(9, 4))
ax1 = fig.add_subplot(121, facecolor="w")
contour = ax1.contour(X, Y, Z, levels=10, cmap="bwr_r")
contour.clabel(fmt='%1.1f', fontsize=11)
ax1.set_title(function_name)
ax1.set_xlabel(my_xlabel, fontsize=12)
ax1.set_ylabel(my_ylabel, fontsize=12)
plt.grid()
print(type(contour))
ax2 = fig.add_subplot(122, projection="3d", facecolor="w")
surf = ax2.plot_surface(X, Y, Z, cmap="bwr_r", alpha=0.9, cstride=1, rstride=1, lw=0.1)
fig.colorbar(surf, shrink=0.6, aspect=10)
ax2.set_title(function_name)
ax2.set_xlabel(my_xlabel, fontsize=12)
ax2.set_ylabel(my_ylabel, fontsize=12)
plt.show()
plt.close()
def my_3Dgraph(X, Y, Z, function_name , u):
print('X -> ' + str(X) + '\n' + str(type(X)))
print('Y -> ' + str(Y) + '\n' + str(type(Y)))
print('Z -> ' + str(Z) + '\n' + str(type(Z)))
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(X, Y, Z, color="red", lw=1)
ax.set_xlabel("X Axis")
ax.set_ylabel("Y Axis")
ax.set_zlabel("Z Axis")
ax.set_title(function_name + '_u' + str(u))
plt.show()
plt.close()
if __name__ == "__main__":
my_xlabel = 'X軸'
my_ylabel = 'Y軸'
X, Y = np.mgrid[-10:11:1, -10:11:1]
Z = my_funcA(X, Y)
my_contur_and_3Dgraph(X, Y, Z, "$z = 6x - x^2 + 4y - y^2$")
Z = my_funcB(X, Y)
my_contur_and_3Dgraph(X, Y, Z, "$z = x^2 - y^2$")
Z = my_funcC(X, Y)
my_contur_and_3Dgraph(X, Y, Z, "$z = x(exp(-(x/5)^2 - (y/5)^2))$")
Z = my_funcD(X, Y)
my_contur_and_3Dgraph(X, Y, Z, "$z = sin(x/2)*sin(y/2)$")
Z = my_funcE(X, Y)
my_contur_and_3Dgraph(X, Y, Z, "$z = cos((x/5)^2 + (y/5)^2)$")
dt = 0.01
num_steps = 10000
xs = np.empty(num_steps + 1)
ys = np.empty(num_steps + 1)
zs = np.empty(num_steps + 1)
xs[0], ys[0], zs[0] = (0., 1., 1.05)
u_list = [1,3,10,30,50]
for my_u in u_list:
for i in range(num_steps):
x_dot, y_dot, z_dot = my_lorenz(xs[i], ys[i], zs[i], a=10, b=8/3, u=my_u)
xs[i + 1] = xs[i] + (x_dot * dt)
ys[i + 1] = ys[i] + (y_dot * dt)
zs[i + 1] = zs[i] + (z_dot * dt)
my_3Dgraph(xs, ys, zs, "Lorenz Attractor", my_u)
print('finished')
(補足)いずれの場合もnumpy配列を使用するため、数学関数を使用する場合もnumpyを使用することです。そうでない場合は、次のようなエラーが出ます。
TypeError: only size-1 arrays can be converted to Python scalars
以上
<広告>
リンク