使用底图对齐地图

时间:2018-05-17 05:08:21

标签: python matplotlib-basemap

有没有办法对齐python底图,如下图所示?enter image description here

以下是制作地图的一些示例底图代码:

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 4.5))
plt.subplots_adjust(left=0.02, right=0.98, top=0.98, bottom=0.00)
m = Basemap(projection='robin',lon_0=0,resolution='c')
m.fillcontinents(color='gray',lake_color='white')
m.drawcoastlines()
plt.savefig('world.png',dpi=75)

1 个答案:

答案 0 :(得分:7)

我不是Matplotlib的专家,但我找到了一种通过使用basemap源文件夹中包含的数据文件获得类似结果的方法。它们可以组合成meshgrid来绘制一些数据,在下面的示例中,我们绘制每个点的高度。

我使用的一个技巧是将matplotlib设置为正交投影,这样地图的垂直间距就不会失真。

我已将参数放在代码的开头,因为您可能会发现调整它很有用。

我无法理解的一件事是地图下的阴影。

from mpl_toolkits.mplot3d import proj3d
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np
import matplotlib.pyplot as plt

# Parameters
n_maps = 5 # Number of maps
z_spacing = 4. # Spacing of maps along z
z_reduction = 1E-8 # Reduction factor for Z data, makes the map look flat
view_angles = (14., -100.) # Set view port angles
colbar_bottom = 0.2 # Space at the bottom of colorbar column
colbar_spacing = .132 # Space between colorbars
colbar_height = 0.1 # Height of colorbars

# Set orthogonal projection
def orthogonal_proj(zfront, zback):
    a = (zfront+zback)/(zfront-zback)
    b = -2*(zfront*zback)/(zfront-zback)
    return np.array([[1,0,0,0],
                     [0,1,0,0],
                     [0,0,a,b],
                     [0,0,-0.0001,zback]])

proj3d.persp_transformation = orthogonal_proj

fig = plt.figure(figsize=[30, 10*n_maps])
ax = fig.gca(projection='3d')

etopo = np.loadtxt('etopo20data.gz')
lons  = np.loadtxt('etopo20lons.gz')
lats  = np.loadtxt('etopo20lats.gz')
# Create Basemap instance for Robinson projection.
m = Basemap(projection='robin', lon_0=0.5*(lons[0]+lons[-1]))
# Compute map projection coordinates for lat/lon grid.
X, Y = m(*np.meshgrid(lons,lats))

# Exclude the oceans
Z = etopo.clip(-1)

# Set the colormap
cmap = plt.cm.get_cmap("terrain")
cmap.set_under("grey")

for i in range(n_maps):
    c = ax.contourf(X, Y, z_spacing*i + z_reduction*Z, 30, cmap=cmap, vmin=z_spacing*i, extend='neither')
    cax = inset_axes(ax,
               width="5%",
               height="100%",
               loc=3,
               bbox_to_anchor=(.85, colbar_spacing*i+colbar_bottom, .2, colbar_height),
               bbox_transform=ax.transAxes,
               borderpad=0
               )
    cb = fig.colorbar(c, cax=cax)
    cb.set_label("Altitude")
    # Reset the ticks of the color bar to match initial data
    cb.set_ticks([z_spacing * i + j/10. * z_reduction * Z.max() for j in range(11)])
    cb.set_ticklabels([str(int(j/10. * Z.max())) for j in range(11)])

ax.set_axis_off()
ax.view_init(*view_angles)
ax.set_xlim3d(X.min(), X.max())
ax.set_ylim3d(Y.min(), Y.max())
ax.set_zlim3d(-1E-2, (n_maps-1)*z_spacing)

plt.savefig('world.png',dpi=75)

Result

修改

如果您想要阴影而不必担心额外的计算时间,您可以使用以下内容更改for循环的开头:

shadow_Z = np.empty(Z.shape)
for i in range(n_maps):
    c = ax.contourf(X, Y, z_spacing*i + z_reduction*Z, 30, cmap=cmaps[i], vmin=z_spacing*i, extend='neither')
    for j in range(10):
        shadow_Z.fill(z_spacing*i - 1E-2 * j)
        s = ax.contourf((X - X.mean()) * (1 + 8E-3 * j) + X.mean() + 2E5, 
                        (Y - Y.mean()) * (1 + 8E-3 * j) + Y.mean() - 2E5, 
                        shadow_Z, colors='black', alpha=0.1 - j * 1E-2)