1. ホーム
  2. python

[解決済み] matplotlib (等しい単位長): 縦横比が「等しい」場合、z軸はx軸とy軸に等しくありません。

2022-11-07 16:10:38

質問

3Dグラフのアスペクト比を等しく設定すると z-axis は「等しい」に変更されません。そこで、この

fig = pylab.figure()
mesFig = fig.gca(projection='3d', adjustable='box')
mesFig.axis('equal')
mesFig.plot(xC, yC, zC, 'r.')
mesFig.plot(xO, yO, zO, 'b.')
pyplot.show()

以下を与える。

ここで、明らかにz軸の単位長さはx軸とy軸の単位と等しくありません。

どうしたら3つの軸の単位長さを等しくすることができるでしょうか。私が見つけたすべての解決策はうまくいきませんでした。

どのように解決するのですか?

matplotlibはまだ3Dで正しく等軸を設定しないと思います...。しかし、私は何回か前に(どこか忘れましたが)トリックを見つけ、それを使って適応させました。コンセプトは、データの周りに偽の立方体のバウンディングボックスを作成することです。 以下のコードでテストできます。

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

fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_aspect('equal')

X = np.random.rand(100)*10+5
Y = np.random.rand(100)*5+2.5
Z = np.random.rand(100)*50+25

scat = ax.scatter(X, Y, Z)

# Create cubic bounding box to simulate equal aspect ratio
max_range = np.array([X.max()-X.min(), Y.max()-Y.min(), Z.max()-Z.min()]).max()
Xb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][0].flatten() + 0.5*(X.max()+X.min())
Yb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][1].flatten() + 0.5*(Y.max()+Y.min())
Zb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][2].flatten() + 0.5*(Z.max()+Z.min())
# Comment or uncomment following both lines to test the fake bounding box:
for xb, yb, zb in zip(Xb, Yb, Zb):
   ax.plot([xb], [yb], [zb], 'w')

plt.grid()
plt.show()

zデータはx,yに比べて一桁ほど大きいのですが、equal axisオプションを付けてもz軸はオートスケールされます。

しかし、バウンディングボックスを追加すると、正しいスケーリングが得られます。