@ImportanceOfBeingErnest noted in a comment으로. 특히 오브젝트는 한 번에 하나씩 렌더링되므로 두 개의 3d 오브젝트가 일반적으로 서로 완전히 앞이나 뒤의 어느 한쪽에 있으므로 matplotlib를 사용하여 3D 오브젝트끼리의 인터 로킹을 거의 불가능하게 만듭니다.
내 개인적인 제안은 mayavi (놀라운 유연성과 시각화, 꽤 가파른 학습 곡선)이지만, 문제를 완전히 제거 할 수있는 트릭을 보여 드리고 싶습니다. 아이디어는 표면 사이의 보이지 않는 다리를 사용하여 두 개의 독립적 인 물체를 하나의 물체로 돌리는 것입니다. 접근의 가능한 단점은 표면보다는 contour3D
로 양면을 플롯 할 필요가
- 것을, 그리고
- 출력 투명성에 크게 의존, 그래서 당신은 그것을 처리 할 수있는 백엔드가 필요합니다.
면책 조항 : 나는 now-defunct Stack Overflow Documentation project의하기 matplotlib 주제에 대한 기여도이 트릭을 배웠지 만, 불행하게도 나는 그 사용자가 누구인지 기억하지 않습니다.
유스 케이스에이 트릭을 사용하려면 기본적으로 contour3D
콜을 다른 plot_surface
으로 호출해야합니다. 나는 이것이 전반적으로 나쁘다고 생각하지 않는다. 결과 그림에 대화식으로 사용할 수있는면이 너무 많으면 절단 평면의 밀도를 재검토해야합니다. 또한 알파 채널이 두 표면 사이의 투명한 다리에 기여하는 점대 점 (point-by-point) 색상 맵을 명시 적으로 정의해야합니다. 두 개의 서페이스를 함께 스티칭해야하기 때문에 서페이스의 적어도 하나의 "평면"차원이 일치해야합니다. 이 경우 두 점에서 "y"의 점이 같은지 확인했습니다. 두 개의 각도에서
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def f(theta1, theta2):
return theta1**2 + theta2**2
fig, ax = plt.subplots(figsize=(6, 6),
subplot_kw={'projection': '3d'})
# plane data: X, Y, Z, C (first three shaped (nx,ny), last one shaped (nx,ny,4))
x,z = np.meshgrid(np.linspace(-1,1,100), np.linspace(0,2,100)) # <-- you can probably reduce these sizes
X = x.T
Z = z.T
Y = 0 * np.ones((100, 100))
# colormap for the plane: need shape (nx,ny,4) for RGBA values
C = np.full(X.shape + (4,), [0,0,0.5,1]) # dark blue plane, fully opaque
# surface data: theta1_grid, theta2_grid, J_grid, CJ (shaped (nx',ny) or (nx',ny,4))
r = np.linspace(-1,1,X.shape[1]) # <-- we are going to stitch the surface along the y dimension, sizes have to match
theta1_grid, theta2_grid = np.meshgrid(r,r)
J_grid = f(theta1_grid, theta2_grid)
# colormap for the surface; scale data to between 0 and 1 for scaling
CJ = plt.get_cmap('binary')((J_grid - J_grid.min())/J_grid.ptp())
# construct a common dataset with an invisible bridge, shape (2,ny) or (2,ny,4)
X_bridge = np.vstack([X[-1,:],theta1_grid[0,:]])
Y_bridge = np.vstack([Y[-1,:],theta2_grid[0,:]])
Z_bridge = np.vstack([Z[-1,:],J_grid[0,:]])
C_bridge = np.full(Z_bridge.shape + (4,), [1,1,1,0]) # 0 opacity == transparent; probably needs a backend that supports transparency!
# join the datasets
X_surf = np.vstack([X,X_bridge,theta1_grid])
Y_surf = np.vstack([Y,Y_bridge,theta2_grid])
Z_surf = np.vstack([Z,Z_bridge,J_grid])
C_surf = np.vstack([C,C_bridge,CJ])
# plot the joint datasets as a single surface, pass colors explicitly, set strides to 1
ax.plot_surface(X_surf, Y_surf, Z_surf, facecolors=C_surf, rstride=1, cstride=1)
ax.set_xlabel(r'$\theta_1$',fontsize='large')
ax.set_ylabel(r'$\theta_2$',fontsize='large')
ax.set_zlabel(r'$J(\theta_1,\theta_2)$',fontsize='large')
ax.set_title(r'Fig.2 $J(\theta_1,\theta_2)=(\theta_1^2+\theta_2^2)$',fontsize='x-large')
plt.tight_layout()
plt.show()
결과 :
당신이 볼 수 있듯이, 결과는 꽤 괜찮은. 서페이스의 개별 투명 필름을 가지고 놀면서 횡단면을 더 잘 보이게 할 수 있는지 알아볼 수 있습니다. 또한 브리지의 불투명도를 1로 전환하여 서페이스가 실제로 어떻게 서로 꿰매어 졌는지 확인할 수도 있습니다.대체로 우리가해야 할 일은 기존 데이터를 가져 와서 크기가 일치하는지 확인하고 명시적인 색상 맵과 서페이스 사이의 보조 브리지를 정의하는 것입니다.
2D 평면이 꺼져있는 경우 :이 모양 만 보입니다. 그것은 정확하게 소유됩니다. 3D 플롯의 경우 : 이것은 [내 3D 플롯이 특정 시야각을 올바르게 보지 못하는] 일반적인 경우 중 하나입니다. (https://matplotlib.org/mpl_toolkits/mplot3d/faq.html#my-3d-plot -doesn-t-look-right-at-certain-viewing-angles). – ImportanceOfBeingErnest
사실 3D Plotting을위한 최적의 선택이 아니라서 Matplotlib에 관한 의견을 찾았습니다. Plotly와 같은 다른 옵션을 살펴 보겠습니다. 고맙습니다 :) –