简体   繁体   English

单位球面上的热图

[英]Heat map on unit sphere

I would like to plot a heat map on the unit sphere using the matplotlib library of python. 我想使用python的matplotlib库在单位球体上绘制热图。 There are several places where this question is discussed. 有几个地方讨论这个问题。 Just like this: Heat Map half-sphere plot 就像这样: 热图半球图

I can do this partially. 我可以部分地做到这一点。 I can creat the sphere and the heatplot. 我可以创造球体和热图。 I have coordinate matrices X,Y and Z, which have the same size. 我有坐标矩阵X,Y和Z,它们具有相同的大小。 I have another variable of the same size as X, Y and Z, which contains scalars used to creat the heat map. 我有另一个与X,Y和Z大小相同的变量,其中包含用于创建热图的标量。 However in case c contains scalars differ from zero in its first and last rows, just one polar cap will be colored but not the other. 但是,如果c包含的标量在其第一行和最后一行中与零不同,则只有一个极性着色而不是另一个。 The code generates the above mentioned result is the next: 代码生成上面提到的结果是下一个:

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()

The plot which was generated: 生成的情节:
单位球面上的热图。

Could somebody help me what's going on here? 有人可以帮我解决这里发生的事吗?

Thank you for your help in advance! 提前谢谢你的帮助!

The values in the arrays define the edges of the grid. 数组中的值定义网格的边缘。 The color of the i th face is determined by the i th value in the color array. i个面的颜色由颜色数组中的第i个值确定。 However, for n edges you only have n-1 faces, such that the last value is ignored. 但是,对于n边,您只有n-1面,因此忽略最后一个值。

Eg if you have 4 grid values and 4 colors, the plot will have only the first three colors in the grid. 例如,如果您有4个网格值和4种颜色,则绘图将只有网格中的前三种颜色。 在此输入图像描述

Thus a solution for the above would be to use a color array with one color less than gridpoints in each dimension. 因此,上述解决方案是使用在每个维度中具有小于网格点的一种颜色的颜色阵列。

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

There are a number of small differences with your example but an important one, namely the shape of the values array c . 您的示例有许多小的差异,但是一个重要的差异,即值数组c的形状。

As mentioned in another answer the grid that defines the surface is larger (by one in both dimensions) than the grid that defines the value in each quadrangular patch, so that by using a smaller array for c it is possible to choose correctly the bands to color not only with respect to the beginnings of the c array but also with respect to its ends, as I tried to demonstrate in the following. 如在另一个答案中所提到的,定义表面的网格比定义每个四边形补丁中的值的网格更大(在两个维度中都是一个),因此通过使用更小的数组用于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()

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM