我正在使用来自另一个SO帖子(Matplotlib scatter plot legend(顶部答案))的代码在3D中绘制基本散点图,但是希望相对于点的“深度”具有与{{1}一样的点不透明度} ax.scatter
。
我不得不使用depthshade=True
,因为ax.plot
似乎无法与3D图上的图例一起使用。
我想知道是否有办法为ax.scatter
获得类似的审美。
谢谢!
答案 0 :(得分:1)
看起来你运气不好,似乎情节没有depthshade=True
功能。我认为问题是情节不允许你以散射方式为每个点设置不同的颜色(或alpha值),我猜测是应用了depthshade的方式。
解决方案是循环遍历所有点并逐个设置颜色,以及mpl_toolkits.mplot3d.art3d.zalpha
辅助函数以提供深度。
import mpl_toolkits
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
n = 100
xs = np.random.rand(n)
ys = np.random.rand(n)
zs = np.random.rand(n)
color = [1,0,0,1]
#Get normal to camera
alpha= ax.azim*np.pi/180.
beta= ax.elev*np.pi/180.
n = np.array([np.cos(alpha)*np.sin(beta),
np.sin(alpha)*np.cos(beta),
np.sin(beta)])
ns = -np.dot(n, [xs, ys, zs])
cs = mpl_toolkits.mplot3d.art3d.zalpha(color, ns)
for i in range(xs.shape[0]):
ax.plot([xs[i]], [ys[i]], [zs[i]], 'o', color=cs[i])
plt.show()
一个棘手的问题是需要使用相机位置ax.elev
和ax.azim
来计算法线向量。此外,当您旋转相机的位置时,它将不再正确着色。要解决此问题,您可以按如下方式注册更新事件,
def Update(event):
#Update normal to camera
alpha= ax.azim*np.pi/180.
beta= ax.elev*np.pi/180.
n = np.array([np.cos(alpha)*np.sin(beta),
np.sin(alpha)*np.cos(beta),
np.sin(beta)])
ns = -np.dot(n, [xs, ys, zs])
cs = mpl_toolkits.mplot3d.art3d.zalpha(color, ns)
for i, p in enumerate(points):
p[0].set_alpha(cs[i][3])
fig.canvas.mpl_connect('draw_event', Update)
points = []
for i in range(xs.shape[0]):
points.append(ax.plot([xs[i]], [ys[i]], [zs[i]], 'o', color=cs[i]))