Matplotlib Plot3D Поверхность / Линия / Точечная диаграмма, как определить z-порядок - PullRequest
1 голос
/ 06 мая 2019

Предисловие: я знаю, что matplotlib не может справиться с 3D окклюзией и что для такого типа проблем я должен использовать Mayavi.Это другая ситуация.

То, чего я пытаюсь добиться, это провести линию поверх поверхности.Линия находится только на «этой» стороне поверхности, поэтому я ожидал, что я смогу контролировать то, что впереди, регулируя zorder.К сожалению, кажется, что zorder ведет себя не так, как ожидалось.

В моем эксперименте ниже, единственное, на что, похоже, влияет zorder, это линейный график, который идет перед разбросом, если zorder> = 3 (независимо от порядка точек рассеяния), и он идет перед поверхностью, если zorder> = 4 (независимо от порядка поверхности).

Насколько я могу судить, matplotlibпросто игнорирует zorder для рассеяния и поверхности и устанавливает их фиксированные значения.Есть ли способ обойти это, т.е. заставить zorder для поверхности и рассеяния?

Вот результат MWE ниже.Линия находится над поверхностью, но точки разброса находятся ниже поверхности.

РЕДАКТИРОВАТЬ: Я только что обнаружил, что мы можем использовать plot и не устанавливать линии, чтобы получить точки, такие как scatter.Он не идеален, потому что мы не можем использовать те же функции scatter, но он работает как обходной путь для построения точек, относящихся к zorder.

Result of the MWE

МВт

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

cos=np.cos
sin=np.sin
arccos=np.arccos
pi = np.pi

def getxyz(in_theta,in_phi,scale=1.0):
    x = scale*sin(in_theta)*cos(in_phi)
    y = scale*sin(in_theta)*sin(in_phi)
    z = scale*cos(in_theta)
    return x,y,z

# ==============  SCRIPT  ================

# Initialize Figure
fig = plt.figure(figsize=(8,8),dpi=100)
ax = fig.add_subplot(111, projection='3d')
ax.set_aspect("equal")


# Plot Sphere Surface-plot
NS=10
Sx,Sy,Sz = getxyz(*np.mgrid[0:pi/2:NS*2j, 0:pi/2:NS*2j])
ax.plot_surface(Sx,Sy,Sz,rstride=2,cstride=2, color=(0.5,0.5,0.5,0.7),zorder=100)

# Make a line on the sphere
Nl=20
Lx,Ly,Lz = getxyz(np.linspace(pi/3,pi/4,Nl),np.linspace(0,pi/3,Nl))

# Plot Scatter
ax.scatter(Lx,Ly,Lz,s=30,c='k',depthshade=False,zorder=500)
# Plot Line
ax.plot(Lx,Ly,Lz,'r-',zorder=4)

ax.view_init(30, 45)
# fig.savefig("test.png")
plt.show()
...