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()