热图半球图 [英] Heat Map half-sphere plot

查看:71
本文介绍了热图半球图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将720 x 180的theta和phi值绘制成 theta范围=(-180至180,步长为0.5) phi范围=(0到-90,步长为0.5)

I want to plot 720 x 180 values of theta and phi into theta range = (-180 to 180 with 0.5 step) phi range = (0 to -90 with 0.5 step)

这是我拥有的数据集的示例:

This is the example of dataset that I have:

Theta Phi Values
-180   0    0.2
-180   0.5  0.5
...    ...  ...
-180   -90  1.1
-179.5  0   0.92
...    ...  ...
 0     -90   0.6
...    ...  ...
180   -89.5 0.17
180   -90   0.12

所以最终,我想得到一个类似的情节:

So eventually, I want to get a similar plot like this one:

我知道如何使用下面的代码创建半球形,但是如何从我的数据框中分配值?

I know how to create the half sphere with the code below, but how can assign the values from my dataframe?

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

# Create a sphere
r = 2
pi = np.pi
cos = np.cos
sin = np.sin
altitude
phi, theta = np.mgrid[0.0:0.5*pi:180j, 0.0:2.0*pi:720j] # phi = alti, theta = azi
x = r*sin(phi)*cos(theta)
y = r*sin(phi)*sin(theta)
z = r*cos(phi)    
#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(
    x, y, z,  rstride=4, cstride=4, color='w', alpha=0.1, linewidth=0)    
ax.set_xlim([-2.2,2.2])
ax.set_ylim([-2.2,2.2])
ax.set_zlim([0,3])
ax.set_aspect("equal")
ax.plot_wireframe(x, y, z, color="k")

代码生成了这个

推荐答案

Axes3D.plot_surface accepts 2D arrays as inputs. It provides the facecolors argument, which accepts an array of the same shape as the input arrays. This array should have the color for each face as rgba tuple in it. One can therefore normalize the array values to the range up to 1 and supply it the a colormap from matplotlib.cm.

然后剩下的问题是从提供的3列列表中获取此数组.给定一个长度为n*m的数据表,其中第一列表示x值,第二个y值和第三个some值,并且其中的排序方式首先是x,然后是y.然后,可以使用.reshape((m,n)).T将最后一列整形为(n,m)数组,其中nx值的数量和y值的m的数量.

The remaining problem is then to obtain this array from the 3 column list which is provided. Given a the datatable of length n*m where the first column denotes x values, second y values and the third some value, and where the sorting is first by x and then by y. One can then reshape the last column to an (n,m) array, where n is the number of x values and m of y values, using .reshape((m,n)).T.

更多说明:

  1. 在下面的解决方案中,我需要模拟该数组,并直接使用辐射角度而不是角度.
  2. 点数180 * 720似乎有点高.为了使窗口不随着年龄的增长,我减少了这个数字.
  3. 我重命名了角度,使它们与通常的教科书定义相匹配,phi =方位角,theta =倾斜角(从z轴开始).
  4. 使用plot_wireframe可能没有太大意义,因为它将隐藏下面的表面.如果需要线框,则可以玩要绘制的点数和linewidth关键字参数.将linewidth设置为较大的值(例如3或5)会使表面看起来不错,将其设置为1会留下一些线框外观.
  1. In the solution below, I needed to mimic this array and directly used angles in radiant, instead of degrees.
  2. The number of points, 180*720 seems a bit high. In order for the window not to take ages to rotate, I decreased that number.
  3. I renamed the angles, such that they match with the usual textbook definition, phi = azimuthal angle, theta=inclination angle (from z axis).
  4. The use of plot_wireframe may not make too much sense, since it will hide the surface below. If a wireframe is desired, one can play with the number of points to be drawn and the linewidth keyword argument. Setting linewidth to something big, like 3 or 5 makes the surface look nice, setting it to 1 leaves some wireframe look.

这是完整的解决方案.

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

#theta inclination angle
#phi azimuthal angle
n_theta = 50 # number of values for theta
n_phi = 200  # number of values for phi
r = 2        #radius of sphere

theta, phi = np.mgrid[0.0:0.5*np.pi:n_theta*1j, 0.0:2.0*np.pi:n_phi*1j]

x = r*np.sin(theta)*np.cos(phi)
y = r*np.sin(theta)*np.sin(phi)
z = r*np.cos(theta)

# mimic the input array
# array columns phi, theta, value
# first n_theta entries: phi=0, second n_theta entries: phi=0.0315..
inp = []
for j in phi[0,:]:
    for i in theta[:,0]:
        val = 0.7+np.cos(j)*np.sin(i+np.pi/4.)# put something useful here
        inp.append([j, i, val])
inp = np.array(inp)
print inp.shape
print inp[49:60, :]

#reshape the input array to the shape of the x,y,z arrays. 
c = inp[:,2].reshape((n_phi,n_theta)).T
print z.shape
print c.shape


#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
#use facecolors argument, provide array of same shape as z
# cm.<cmapname>() allows to get rgba color from array.
# array must be normalized between 0 and 1
ax.plot_surface(
    x,y,z,  rstride=1, cstride=1, facecolors=cm.hot(c/c.max()), alpha=0.9, linewidth=1) 
ax.set_xlim([-2.2,2.2])
ax.set_ylim([-2.2,2.2])
ax.set_zlim([0,4.4])
ax.set_aspect("equal")
#ax.plot_wireframe(x, y, z, color="k") #not needed?!
plt.savefig(__file__+".png")
plt.show()

这篇关于热图半球图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆