相对于深度matplotlib 3D点图的点不透明度

时间:2018-04-12 18:12:32

标签: python matplotlib plot 3d opacity

我正在使用来自另一个SO帖子(Matplotlib scatter plot legend(顶部答案))的代码在3D中绘制基本散点图,但是希望相对于点的“深度”具有与{{1}一样的点不透明度} ax.scatter

enter image description here

我不得不使用depthshade=True,因为ax.plot似乎无法与3D图上的图例一起使用。

我想知道是否有办法为ax.scatter获得类似的审美。

谢谢!

1 个答案:

答案 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.elevax.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]))