[PYTHON] matplotlib (동일한 단위 길이) : '동일'종횡비와 함께 z 축은 x 및 y 축과 동일하지 않습니다.
PYTHONmatplotlib (동일한 단위 길이) : '동일'종횡비와 함께 z 축은 x 및 y 축과 동일하지 않습니다.
3d 그래프에 대해 동일한 종횡비를 설정하면 z 축이 '동일'으로 변경되지 않습니다. 그래서 이거:
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 단위와 동일하지 않습니다.
세 축의 단위 길이를 어떻게 같게 만들 수 있습니까? 찾을 수있는 모든 솔루션이 작동하지 않았습니다. 고맙습니다.
해결법
-
==============================
1.나는 matplotlib이 아직 3D에서 동등한 축을 올바르게 설정하지 않았다고 믿습니다 ... 그러나 나는 그것을 사용하여 적응 한 트릭을 몇 번이나 (나는 기억이 안납니다.) 발견했습니다. 개념은 데이터 주위에 가짜 입방 경계 상자를 만드는 것입니다. 다음 코드를 사용하여 테스트 할 수 있습니다.
나는 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.gca(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보다 큰 순서이지만, 동일한 축 옵션이 있더라도 matplotlib 자동 축 z 축 :
그러나 테두리 상자를 추가하면 올바른 크기 조정을 얻을 수 있습니다.
-
==============================
2.나는 set_x / y / zlim 함수를 사용하여 Remy F의 해를 단순화했다.
나는 set_x / y / zlim 함수를 사용하여 Remy F의 해를 단순화했다.
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt import numpy as np fig = plt.figure() ax = fig.gca(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) max_range = np.array([X.max()-X.min(), Y.max()-Y.min(), Z.max()-Z.min()]).max() / 2.0 mid_x = (X.max()+X.min()) * 0.5 mid_y = (Y.max()+Y.min()) * 0.5 mid_z = (Z.max()+Z.min()) * 0.5 ax.set_xlim(mid_x - max_range, mid_x + max_range) ax.set_ylim(mid_y - max_range, mid_y + max_range) ax.set_zlim(mid_z - max_range, mid_z + max_range) plt.show()
-
==============================
3.위의 솔루션이 마음에 들지만 모든 데이터에 대해 범위와 수단을 추적해야한다는 단점이 있습니다. 여러 개의 데이터 세트가 함께 플롯 될 경우이 작업은 번거로울 수 있습니다. 이를 해결하기 위해 ax.get_ [xyz] lim3d () 메서드를 사용하고 plt.show ()를 호출하기 전에 단 한 번만 호출 할 수있는 독립 실행 형 함수로 모든 것을 넣었습니다. 다음은 새 버전입니다.
위의 솔루션이 마음에 들지만 모든 데이터에 대해 범위와 수단을 추적해야한다는 단점이 있습니다. 여러 개의 데이터 세트가 함께 플롯 될 경우이 작업은 번거로울 수 있습니다. 이를 해결하기 위해 ax.get_ [xyz] lim3d () 메서드를 사용하고 plt.show ()를 호출하기 전에 단 한 번만 호출 할 수있는 독립 실행 형 함수로 모든 것을 넣었습니다. 다음은 새 버전입니다.
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt import numpy as np def set_axes_equal(ax): '''Make axes of 3D plot have equal scale so that spheres appear as spheres, cubes as cubes, etc.. This is one possible solution to Matplotlib's ax.set_aspect('equal') and ax.axis('equal') not working for 3D. Input ax: a matplotlib axis, e.g., as output from plt.gca(). ''' x_limits = ax.get_xlim3d() y_limits = ax.get_ylim3d() z_limits = ax.get_zlim3d() x_range = abs(x_limits[1] - x_limits[0]) x_middle = np.mean(x_limits) y_range = abs(y_limits[1] - y_limits[0]) y_middle = np.mean(y_limits) z_range = abs(z_limits[1] - z_limits[0]) z_middle = np.mean(z_limits) # The plot bounding box is a sphere in the sense of the infinity # norm, hence I call half the max range the plot radius. plot_radius = 0.5*max([x_range, y_range, z_range]) ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius]) ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius]) ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius]) fig = plt.figure() ax = fig.gca(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) set_axes_equal(ax) plt.show()
-
==============================
4.편집 : user2525140의 코드는 완벽하게 잘 작동해야하지만,이 응답은 존재하지 않는 오류를 수정하려고 시도했을 것입니다. 아래 답변은 중복 된 (대체) 구현입니다.
편집 : user2525140의 코드는 완벽하게 잘 작동해야하지만,이 응답은 존재하지 않는 오류를 수정하려고 시도했을 것입니다. 아래 답변은 중복 된 (대체) 구현입니다.
def set_aspect_equal_3d(ax): """Fix equal aspect bug for 3D plots.""" xlim = ax.get_xlim3d() ylim = ax.get_ylim3d() zlim = ax.get_zlim3d() from numpy import mean xmean = mean(xlim) ymean = mean(ylim) zmean = mean(zlim) plot_radius = max([abs(lim - mean_) for lims, mean_ in ((xlim, xmean), (ylim, ymean), (zlim, zmean)) for lim in lims]) ax.set_xlim3d([xmean - plot_radius, xmean + plot_radius]) ax.set_ylim3d([ymean - plot_radius, ymean + plot_radius]) ax.set_zlim3d([zmean - plot_radius, zmean + plot_radius])
-
==============================
5.@ karlo의 답변을 수정하여 더욱 깨끗하게 만듭니다.
@ karlo의 답변을 수정하여 더욱 깨끗하게 만듭니다.
def set_axes_radius(ax, origin, radius): ax.set_xlim3d([origin[0] - radius, origin[0] + radius]) ax.set_ylim3d([origin[1] - radius, origin[1] + radius]) ax.set_zlim3d([origin[2] - radius, origin[2] + radius]) def set_axes_equal(ax): '''Make axes of 3D plot have equal scale so that spheres appear as spheres, cubes as cubes, etc.. This is one possible solution to Matplotlib's ax.set_aspect('equal') and ax.axis('equal') not working for 3D. Input ax: a matplotlib axis, e.g., as output from plt.gca(). ''' limits = np.array([ ax.get_xlim3d(), ax.get_ylim3d(), ax.get_zlim3d(), ]) origin = np.mean(limits, axis=1) radius = 0.5 * np.max(np.abs(limits[:, 1] - limits[:, 0])) set_axes_radius(ax, origin, radius)
용법:
fig = plt.figure() ax = fig.gca(projection='3d') ax.set_aspect('equal') # important! # ...draw here... set_axes_equal(ax) # important! plt.show()
from https://stackoverflow.com/questions/13685386/matplotlib-equal-unit-length-with-equal-aspect-ratio-z-axis-is-not-equal-to by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] '로그'와 'symlog'의 차이점은 무엇입니까? (0) | 2018.10.10 |
---|---|
[PYTHON] HTML 링크에서 URL을 추출하는 정규 표현식 (0) | 2018.10.10 |
[PYTHON] tensorflow에서 현재 사용 가능한 GPU를 얻는 방법? (0) | 2018.10.10 |
[PYTHON] 블로킹 및 비 블로킹 서브 프로세스 호출 (0) | 2018.10.10 |
[PYTHON] Python의 특수 (매직) 메소드 [닫힘] (0) | 2018.10.10 |