我写了一个函数(参见结束),它计算特定顺序和度数的球谐系数,并将它们绘制在球体上。
我尝试使用plt.subplots和plt.gridSpec两个图表无济于事。它总是最终将其他情节放在外面。这是我尝试过的代码:
fig, axes = plt.subplots(ncols=1, nrows=2)
ax1, ax2 = axes.ravel()
ax1.plot(sh(6,6))
ax2.plot(sh(7,7))
plt.show()
我得到了下图:
和追溯@第3行:
ValueError:x和y不能为None
此外,
### GridSpec ####
plt.subplot2grid((2,2), (0,0))
sh(7,7)
plt.subplot2grid((2,2), (1, 0))
sh(8,7)
plt.subplot2grid((2,2), (1, 1))
sh(9,7)
plt.show()
产生3个独立的(非网格)图。
这是一个更好的结果,但第三个球体应位于第二个球体的右侧,除非我做错了什么。 注意:sh()是我写的函数,用于计算球面谐波和用球面谐波投影绘制球体。换句话说,我在这里有2个球。我想要做的就是将两个(实际上更多)球体组合成一个像上面那样的网格。
PS:我曾尝试与Mayavi合作,但我无法使其发挥作用。网站上的所有代码对我都不起作用。我稍后会重新检查,但我现在很紧张,所以我写了自己的功能。我写的功能:
def sh(l,m,cent_lat,cent_lon):
# function that calculates the spherical harmonics of order l and degree m and visualizes it on a
# sphere centered at (cent_lat, cent_lon) given in degrees
if l < m:
print "Order cannot be smaller than the degree! Try again."
else:
import numpy as np
import scipy.special as sp
from math import pi
import matplotlib.cm as cm
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
res = pi/100 # resolution
theta = np.r_[0:2*pi:res]; phi = np.r_[0:pi:res] # theta: lon, phi: coalt
coef = []
for i in theta:
for j in phi:
coef.append(sp.sph_harm(m,l,i,j))
coef = np.asarray(coef) # convert list to array
coef = np.reshape(coef, (len(theta),-1)) # reshapte array as per number of angles
## Plotting ##
# create lat/lon arrays
lon = np.linspace(0,2*pi,len(theta))
lat = np.linspace(-pi/2,pi/2,len(phi))
colat = lat+pi/2 # colatitude array
# create 2D meshgrid
mesh_grid = np.meshgrid(lon, lat) # create a meshgrid out of lat/lon
lon_grid = mesh_grid[0] # grab the meshgrid part for lon
lat_grid = mesh_grid[1] # grab the meshgrid part for lat
real_coef = np.real(coef) # read parts of the coefficients
norm_coef = np.round(real_coef / np.max(real_coef),2) # normalize
# set up orthographic map projection
mp = Basemap(projection='ortho', lat_0 = cent_lat, lon_0 = cent_lon) # setup an orthographic basemap centered at lat_0 & lon_0
# draw the edge of the map projection region (the projection limb)
mp.drawmapboundary()
# convert angles from radians to degrees & pipe them to basemap
x,y = mp(np.degrees(lon_grid), np.degrees(lat_grid))
cmap = cm.get_cmap('jet') # Set color map
mp.pcolor(x,y,np.transpose(norm_coef), cmap=cmap)
# cax = figure.add_axes([0.15,0.03,0.7,0.03])
# cb = plt.colorbar(orientation = 'horizontal')
plt.show()
感谢任何帮助。
答案 0 :(得分:3)
GridSpec
适用于我(matplotlib
v1.5.0,如果重要的话):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.colors import LightSource
import matplotlib.cm as cm
import matplotlib.gridspec as gridspec
import numpy as np
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ls = LightSource(270, 45)
rgb = ls.shade(z, cmap=cm.gist_earth, vert_exag=0.1, blend_mode='soft')
def plot_sphere(s):
s.plot_surface(x, y, z, rstride=4, cstride=4, facecolors=rgb,
linewidth=0, antialiased=False, shade=False)
s.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
s.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
s.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
s.w_xaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
s.w_yaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
s.w_zaxis.line.set_color((1.0, 1.0, 1.0, 0.0))
s.set_xticks([])
s.set_yticks([])
s.set_zticks([])
fig = plt.figure()
gs = gridspec.GridSpec(6, 7)
for i in range(6):
for j in range(6):
if i >= j:
s = fig.add_subplot(gs[i,j+1], projection='3d')
plot_sphere(s)
for i in range(6):
pos = gs[i,0].get_position(fig)
fig.text(pos.x0, (pos.y0 + pos.y1) / 2, "$\\ell = " + str(i) + "$", fontsize=16)
fig.savefig('t.png')