使用Matplotlib在球面上根据一组标量值进行着色

6

我对matplotlib比较陌生(这也是我在这里的第一个问题)。我正在尝试表示由EEG记录的头皮表面电位。到目前为止,我已经生成了一个平面投影的二维图形,使用contourf生成,基本上可以归结为普通的热图。

是否有办法在半球上完成这个操作?也就是说,生成一个3D的球体,其表面颜色由值列表给出?类似于这样 http://embal.gforge.inria.fr/img/inverse.jpg,但我只需要半个球就足够了。

我看到了一些相关的问题(例如Matplotlib 3d colour plot - is it possible?),但它们要么没有真正回答我的问题,要么仍然无解。

我还花了整个早上查找无数的示例。在我找到的大多数示例中,表面一个特定点的颜色与其Z值有关,但我不想要那样...我想先绘制表面,然后使用我有的数据指定颜色。

1个回答

13
你可以使用 plot_trisurf 方法,并通过 set_array 方法将自定义字段分配给底层的 ScalarMappable
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.tri as mtri

(n, m) = (250, 250)

# Meshing a unit sphere according to n, m 
theta = np.linspace(0, 2 * np.pi, num=n, endpoint=False)
phi = np.linspace(np.pi * (-0.5 + 1./(m+1)), np.pi*0.5, num=m, endpoint=False)
theta, phi = np.meshgrid(theta, phi)
theta, phi = theta.ravel(), phi.ravel()
theta = np.append(theta, [0.]) # Adding the north pole...
phi = np.append(phi, [np.pi*0.5])
mesh_x, mesh_y = ((np.pi*0.5 - phi)*np.cos(theta), (np.pi*0.5 - phi)*np.sin(theta))
triangles = mtri.Triangulation(mesh_x, mesh_y).triangles
x, y, z = np.cos(phi)*np.cos(theta), np.cos(phi)*np.sin(theta), np.sin(phi)

# Defining a custom color scalar field
vals = np.sin(6*phi) * np.sin(3*theta)
colors = np.mean(vals[triangles], axis=1)

# Plotting
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cmap = plt.get_cmap('Blues')
triang = mtri.Triangulation(x, y, triangles)
collec = ax.plot_trisurf(triang, z, cmap=cmap, shade=False, linewidth=0.)
collec.set_array(colors)
collec.autoscale()
plt.show()

在这里输入图片描述


谢谢。它现在无法正常工作,但我认为这是因为我使用的是1.1.1版本。我会尝试升级,如果这是问题的原因,我会立即接受你的答案。 - lambda
1
以防将来有人遇到同样的问题,这个解决方案确实需要最新版本(截至目前为止,1.3.1)的matplotlib。此外,是否有任何方法可以使颜色不是位置的函数?我一直在尝试将值列表传递给您的解决方案,但我无法使其工作。 - lambda
1
感谢您的准确回答。关于您的问题,确实是可能的:只需将大小为ntri(三角形数量)的一维数组传递给collec.set_array即可。如果您只知道节点值,则必须按三角形平均它们,这就是我在代码块“#定义自定义颜色标量场”中所做的。或者我有什么遗漏吗? - GBy
很好的回答 - 但是当三角形数量很大时(比如大约70,000个),我遇到了问题,此时我的电脑在尝试绘图时会出现某种内存问题,程序就会崩溃。 - Dipole
非常感谢!这个 collec.set_array(colors) 就像魔法一样! - CodingNow
谢谢你的回答!我看到你的球体在南极没有连接,有什么办法可以解决这个问题吗?比如在三角测量步骤中,是否有一种方法可以确定边界? - A. Jahin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接