python/matplotlib을 사용하여 3D 플롯에 대한 "카메라 위치"를 설정하는 방법은 무엇입니까?
저는 mplot3d를 사용하여 3d 데이터의 멋진 플롯을 만드는 방법을 배우고 있으며 지금까지 꽤 만족합니다.제가 지금 하려고 하는 것은 회전하는 표면의 작은 애니메이션입니다.그러기 위해서는 3D 투영을 위한 카메라 위치를 설정해야 합니다.matplotlib을 대화형으로 사용할 때 마우스를 사용하여 표면을 회전시킬 수 있기 때문에 가능할 것으로 생각합니다.하지만 스크립트에서 이 작업을 수행하려면 어떻게 해야 합니까?mpl_toolkits.mplot3d.proj3d에서 많은 변환을 찾았지만, 이 변환들을 내 목적에 맞게 사용하는 방법을 찾을 수 없었고 내가 하려는 작업에 대한 예도 찾을 수 없었습니다.
카메라 위치는 3D 그림을 보는 데 사용하는 표고와 방위각을 조정하려는 것처럼 들립니다.로 설정할 수 있습니다. 먼저 아래 스크립트를 사용하여 플롯을 작성한 다음 적절한 표고를 결정했습니다.elev
내 음모를 볼 수 있는 곳.그리고 방위각을 조정했습니다.azim
그림 주위의 전체 360도를 변경하여 각 인스턴스에서 그림을 저장합니다(그림을 저장할 때 어떤 방위각을 사용하는지 기록).더 복잡한 카메라 팬의 경우 원하는 효과를 얻기 위해 표고와 각도를 모두 조정할 수 있습니다.
from mpl_toolkits.mplot3d import Axes3D
ax = Axes3D(fig)
ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6)
for ii in xrange(0,360,1):
ax.view_init(elev=10., azim=ii)
savefig("movie%d.png" % ii)
카메라 위치를 새 플롯에 적용하면 편리합니다.그래서 저는 그림을 그리고 마우스로 거리를 바꾸면서 그림을 움직입니다.그런 다음 다른 그림의 거리를 포함하여 뷰를 복제합니다.axx.ax .get_dll은 이전 .azim 및 .dll을 가진 개체를 가져옵니다.
PYTHON에서...
axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev
dst=axx.dist # ALWAYS GIVES 10
#dst=ax1.axes.dist # ALWAYS GIVES 10
#dst=ax1.dist # ALWAYS GIVES 10
나중에 3D 그래프...
ax2.view_init(elev=ele, azim=azm) #Works!
ax2.dist=dst # works but always 10 from axx
EDIT 1...좋아요, 카메라 위치는 .dist 값에 대한 잘못된 생각입니다.그것은 전체 그래프에 대한 일종의 해커키 스칼라 승수로 모든 것 위에 올라갑니다.
이 기능은 보기의 확대/축소에 사용됩니다.
xlm=ax1.get_xlim3d() #These are two tupples
ylm=ax1.get_ylim3d() #we use them in the next
zlm=ax1.get_zlim3d() #graph to reproduce the magnification from mousing
axx=ax1.get_axes()
azm=axx.azim
ele=axx.elev
나중에 그래프...
ax2.view_init(elev=ele, azim=azm) #Reproduce view
ax2.set_xlim3d(xlm[0],xlm[1]) #Reproduce magnification
ax2.set_ylim3d(ylm[0],ylm[1]) #...
ax2.set_zlim3d(zlm[0],zlm[1]) #...
변동하는 최소 예제azim
,dist
그리고.elev
https://stackoverflow.com/a/12905458/895245 에서 설명한 내용에 간단한 샘플 이미지를 추가합니다.
내 테스트 프로그램은 다음과 같습니다.
#!/usr/bin/env python3
import sys
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
if len(sys.argv) > 1:
azim = int(sys.argv[1])
else:
azim = None
if len(sys.argv) > 2:
dist = int(sys.argv[2])
else:
dist = None
if len(sys.argv) > 3:
elev = int(sys.argv[3])
else:
elev = None
# Make data.
X = np.arange(-5, 6, 1)
Y = np.arange(-5, 6, 1)
X, Y = np.meshgrid(X, Y)
Z = X**2
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, linewidth=0, antialiased=False)
# Labels.
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
if azim is not None:
ax.azim = azim
if dist is not None:
ax.dist = dist
if elev is not None:
ax.elev = elev
print('ax.azim = {}'.format(ax.azim))
print('ax.dist = {}'.format(ax.dist))
print('ax.elev = {}'.format(ax.elev))
plt.savefig(
'main_{}_{}_{}.png'.format(ax.azim, ax.dist, ax.elev),
format='png',
bbox_inches='tight'
)
인수 없이 실행하면 다음과 같은 기본값이 제공되는 값은 다음과 같습니다.
ax.azim = -60
ax.dist = 10
ax.elev = 30
메인_-60_10_30.png
다르다azim
방위각은 z축을 중심으로 한 회전입니다. 예:
- 0은 "+x에서 바라보기"를 의미합니다.
- 90은 "+y에서 바라보기"를 의미합니다.
메인_-60_10_30.png
메인_0_10_30.png
메인_60_10_30.png
다르다dist
dist
는 데이터 좌표의 중심 가시점으로부터의 거리로 보입니다.
메인_-60_10_30.png
메인_-60_5_30.png
메인_-60_20_-30.png
다르다elev
이를 통해 우리는 이해합니다.elev
눈과 xy 평면 사이의 각도입니다.
메인_-60_10_60.png
메인_-60_10_30.png
메인_-60_10_0.png
메인_-60_10_-30.png
matpotlib==3.2.2에서 테스트되었습니다.
다음 코드를 사용하여 최적의 카메라 위치를 찾습니다.
if 절에 언급된 대로 키보드 키를 사용하여 플롯의 시야각을 이동합니다.
인쇄를 사용하여 카메라 위치 가져오기
def move_view(event):
ax.autoscale(enable=False, axis='both')
koef = 8
zkoef = (ax.get_zbound()[0] - ax.get_zbound()[1]) / koef
xkoef = (ax.get_xbound()[0] - ax.get_xbound()[1]) / koef
ykoef = (ax.get_ybound()[0] - ax.get_ybound()[1]) / koef
## Map an motion to keyboard shortcuts
if event.key == "ctrl+down":
ax.set_ybound(ax.get_ybound()[0] + xkoef, ax.get_ybound()[1] + xkoef)
if event.key == "ctrl+up":
ax.set_ybound(ax.get_ybound()[0] - xkoef, ax.get_ybound()[1] - xkoef)
if event.key == "ctrl+right":
ax.set_xbound(ax.get_xbound()[0] + ykoef, ax.get_xbound()[1] + ykoef)
if event.key == "ctrl+left":
ax.set_xbound(ax.get_xbound()[0] - ykoef, ax.get_xbound()[1] - ykoef)
if event.key == "down":
ax.set_zbound(ax.get_zbound()[0] - zkoef, ax.get_zbound()[1] - zkoef)
if event.key == "up":
ax.set_zbound(ax.get_zbound()[0] + zkoef, ax.get_zbound()[1] + zkoef)
# zoom option
if event.key == "alt+up":
ax.set_xbound(ax.get_xbound()[0]*0.90, ax.get_xbound()[1]*0.90)
ax.set_ybound(ax.get_ybound()[0]*0.90, ax.get_ybound()[1]*0.90)
ax.set_zbound(ax.get_zbound()[0]*0.90, ax.get_zbound()[1]*0.90)
if event.key == "alt+down":
ax.set_xbound(ax.get_xbound()[0]*1.10, ax.get_xbound()[1]*1.10)
ax.set_ybound(ax.get_ybound()[0]*1.10, ax.get_ybound()[1]*1.10)
ax.set_zbound(ax.get_zbound()[0]*1.10, ax.get_zbound()[1]*1.10)
# Rotational movement
elev=ax.elev
azim=ax.azim
if event.key == "shift+up":
elev+=10
if event.key == "shift+down":
elev-=10
if event.key == "shift+right":
azim+=10
if event.key == "shift+left":
azim-=10
ax.view_init(elev= elev, azim = azim)
# print which ever variable you want
ax.figure.canvas.draw()
fig.canvas.mpl_connect("key_press_event", move_view)
plt.show()
Q: matplotlib에서 뷰를 설정하려면 어떻게 해야 합니까?
3D 그림의 경우 뷰를 고정하는 방법은 무엇입니까?
A: 속을설정다니합성▁proper다▁settingties를 설정함으로써.ax.azim
그리고.ax.level
ax.elev = 0
ax.azim = 270 # xz view
ax.elev = 0
ax.azim = 0 # yz view
ax.elev = 0
ax.azim = -90 # xy view
언급URL : https://stackoverflow.com/questions/12904912/how-to-set-camera-position-for-3d-plots-using-python-matplotlib
'programing' 카테고리의 다른 글
R: 자체 작성 패키지에서 Magritr 파이프 연산자 사용 (0) | 2023.06.09 |
---|---|
레일 4: 사용 가능한 데이터 유형 목록 (0) | 2023.06.09 |
Vuex getter는 항상 null을 반환합니다. (0) | 2023.06.09 |
텍스트 상자가 활성화되면 내용을 선택하는 방법은 무엇입니까? (0) | 2023.06.09 |
인덱스 변수 없이 N번 무언가를 하는 파이썬적인 방법? (0) | 2023.06.04 |