单位球面上的热图

Heat map on unit sphere

我想使用 python 的 matplotlib 库在单位球体上绘制热图。有几个地方讨论了这个问题。就像这样:

我可以部分做到这一点。我可以创建球体和热图。我有坐标矩阵 X、Y 和 Z,它们具有相同的大小。我有另一个与 X、Y 和 Z 大小相同的变量,其中包含用于创建热图的标量。然而,如果 c 在其第一行和最后一行包含不为零的标量,则只有一个极冠会被着色,而另一个不会。代码生成上面提到的结果是下一个:

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

#Creating the theta and phi values.
theta = np.linspace(0,np.pi,100,endpoint=True)
phi   = np.linspace(0,np.pi*2,100,endpoint=True)

#Creating the coordinate grid for the unit sphere.
X = np.outer(np.sin(theta),np.cos(phi))
Y = np.outer(np.sin(theta),np.sin(phi))
Z = np.outer(np.cos(theta),np.ones(100))

#Creating a 2D matrix contains the values used to color the unit sphere.
c = np.zeros((100,100))
for i in range(100):
    c[0,i]  = 100
    c[99,i] = 100

#Creat the plot.
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.set_axis_off()
ax.plot_surface(X,Y,Z, rstride=1, cstride=1, facecolors=cm.plasma(c/np.amax(c)), alpha=0.22, linewidth=1)
m = cm.ScalarMappable(cmap=cm.plasma)
m.set_array(c)
plt.colorbar(m)

#Show the plot.
plt.show()

生成的情节:

有人能帮我看看这是怎么回事吗?

提前感谢您的帮助!

数组中的值定义了网格的边缘。第 i 个面的颜色由颜色数组中的第 i 个值决定。但是,对于 n 个边,您只有 n-1 个面,因此最后一个值将被忽略。

例如如果您有 4 个网格值和 4 种颜色,绘图将只有网格中的前三种颜色。

因此,上述问题的解决方案是使用一个颜色数组,每个维度中的颜色比网格点少一种。

c = np.zeros((99,99))
c[[0,98],:] = 100

你的例子有一些小的不同,但是 重要的一个,即值数组的形状 c.

另一篇所述 answer 网格 定义表面比 定义每个四边形补丁中的值的网格,以便通过 为 c 使用较小的数组可以正确选择 带不仅在 c 的开头着色 数组,但也关于它的末端,正如我试图在 以下。

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

# Creating the theta and phi values.

intervals = 8
ntheta = intervals
nphi = 2*intervals

theta = np.linspace(0, np.pi*1, ntheta+1)
phi   = np.linspace(0, np.pi*2, nphi+1)

# Creating the coordinate grid for the unit sphere.
X = np.outer(np.sin(theta), np.cos(phi))
Y = np.outer(np.sin(theta), np.sin(phi))
Z = np.outer(np.cos(theta), np.ones(nphi+1))

# Creating a 2D array to be color-mapped on the unit sphere.
# {X, Y, Z}.shape → (ntheta+1, nphi+1) but c.shape → (ntheta, nphi)
c = np.zeros((ntheta, nphi)) + 0.4
# The poles are different
c[ :1, :] = 0.8
c[-1:, :] = 0.8
# as well as the zones across Greenwich
c[:,  :1] = 0.0
c[:, -1:] = 0.0

# Creating the colormap thingies.
cm = mpl.cm.inferno
sm = mpl.cm.ScalarMappable(cmap=cm)
sm.set_array([])

# Creating the plot.
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=cm(c), alpha=0.3)
plt.colorbar(m)

# Showing the plot.
plt.show()