Pythonで3次元プロット と回転 matplotlib 3.7.1
matplotlibの2くらいから「パースペクティブ」の解除は一語に代わっていた。
matplotlibでパースペクティブの解除について、昔は少しコードを書かないといけなかった。
がそれは今は昔の話で、ax.set_proj_type('ortho');で一発となっていた。
まえに記事を書いてから5年近くたっているから当然かな。
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def rotX(X): theta = X / 180.0 * np.pi; Rx = np.array([[1,0,0,0], [0,np.cos(theta),np.sin(theta),0], [0,-np.sin(theta),np.cos(theta),0], [0,0,0,1]]); return Rx; def rotY(Y): theta = Y / 180.0 * np.pi; Ry = np.array([[np.cos(theta),0,-np.sin(theta),0], [0,1,0,0], [np.sin(theta),0,np.cos(theta),0], [0,0,0,1]]); return Ry; def rotZ(Z): theta = Z / 180.0 * np.pi; Rz = np.array([[np.cos(theta),np.sin(theta),0,0], [-np.sin(theta),np.cos(theta),0,0], [0,0,1,0], [0,0,0,1]]); return Rz; def trans(x): Tr = np.array([[1,0,0,x[0]], [0,1,0,x[1]], [0,0,1,x[2]], [0,0,0,1]]); return Tr; def main(): r = 50.0; theta = np.arange(0.0, 360.0, 30.0); x = np.array([]); y = np.array([]); z = np.array([]); for i in range(10): x_ = r * np.cos(theta / 180.0 * np.pi); y_ = r * np.sin(theta / 180.0 * np.pi); z_ = 10.0 * i * np.ones(x_.shape[0]); x = np.append(x, x_); y = np.append(y, y_); z = np.append(z, z_); X = np.array([x, y, z, np.ones(x.shape[0])]); X = np.dot(rotX(45.0), X); X = np.dot(rotY(45.0), X); X = np.dot(rotZ(10.0), X); X = np.dot(trans([10, 10, -10]), X); fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.set_proj_type('ortho'); ax.scatter3D(X[0], X[1], X[2]); ax.set_aspect('equal') plt.grid() plt.savefig('plot201803.svg'); plt.show(); if __name__ == '__main__': main()
しかも、バックエンドとしてWebAggを使用するとWebブラウザから3D図をグリグリ操作できる(tornadoパッケージも必要)。私はWebView2と組み合わせて.NETアプリとPythonアプリの組み合わせで使ってみようかと思っています。
(バックエンドをWebAggに切り替えただけでは、show()のところでWebブラウザが起動してしまうところが問題だがほかのアプリへの組み込み方があるらしい)
if __name__ == '__main__': plt.rcParams['webagg.open_in_browser'] = False; plt.rcParams['webagg.address'] = '0.0.0.0'; plt.switch_backend('WebAgg'); main()
タグ:Python