programing

python/matplotlib을 사용하여 3D 플롯에 대한 "카메라 위치"를 설정하는 방법은 무엇입니까?

css3 2023. 6. 9. 22:16

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