我正在使用matplotlib底图制作飞机数据的3D图。我找到了一种方法,即basemap.drawmeridians和basemap.drawparallels不能与3D轴一起使用。但是,我对最后一个问题感到难过。除非设置了ax.set_zlims
关键字,否则手动绘制的子午线和平行线不会与轴对齐。因此,如果没有关键字,请将图片设为grid is displaced,而使用关键字设置grid lines up
相关代码:
fig = plt.gcf()
ax = fig.add_subplot(111, projection='3d')
# Create a basemap instance
bm = Basemap(projection=proj, resolution=resolution,
area_thresh=area_thresh,
llcrnrlon=corners[0], urcrnrlon=corners[2],
llcrnrlat=corners[1], urcrnrlat=corners[3],
lon_0=lon_0, lat_0=lat_0, ax=ax)
# Now we need to create a "fake" axes instance because
# the drawmeridians and drawparallels will not otherwise work
ax2D = Axes(fig, [0, 0, 1, 1])
bm2 = Basemap(projection=proj, resolution=resolution,
area_thresh=area_thresh,
llcrnrlon=corners[0], urcrnrlon=corners[2],
llcrnrlat=corners[1], urcrnrlat=corners[3],
lon_0=lon_0, lat_0=lat_0, ax=ax2D)
llxc, llyc = bm2(corners[0], corners[1])
urxc, uryc = bm2(corners[2], corners[3])
if xpad is None:
xpad = 1.
xoffset = ((urxc - llxc)/100.) * xpad
if ypad is None:
ypad = 1.
yoffset = ((uryc - llyc)/100.) * ypad
# Check the customizations for the basemap
if meridians:
lons = np.arange(corners[0], corners[2], lon_spacing)
latax = np.full(np.shape(lons), corners[1])
bmlon = bm2.drawmeridians(lons, labels=[1, 0, 0, 1]
xm, ym = bm2(lons, latax)
llxm, llym = bm2(lons[0], corners[1])
urxm, urym = bm2(lons[-1], corners[3])
for i, mm in enumerate(bmlon.keys()):
ax.plot([xm[i], xm[i]], [llym, urym], zs=0.,
color='0.92', ls=':')
ax.text(xm[i], llym - yoffset, 0., np.str(mm),
horizontalalignment='center', verticalalignment='top')
if parallels:
lats = np.arange(corners[1], corners[3], lat_spacing)
lonax = np.full(np.shape(lats), corners[2])
bmlat = bm2.drawparallels(lats, labels=[1, 0, 0, 1])
xp, yp = bm2(lonax, lats)
llxp, llyp = bm2(corners[0], lats[0])
urxp, uryp = bm2(corners[2], lats[-1])
for i, pp in enumerate(bmlat.keys()):
ax.plot([llxp, urxp], [xm[i], xm[i]], zs=0.,
color='0.88', ls=':')
ax.text(urxc + xoffset, yp[i], 0., np.str(pp),
horizontalalignment='left', verticalalignment='center')
ax.add_collection3d(bm.drawstates())
p = ax.plot(x, y, altmask, color=track_color,
linewidth=lw, linestyle=ls, alpha=alpha)
# Label the axes
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
ax.set_zlabel('Altitude (m)')
ax.set_xlim3d(np.min(x), np.max(x))
ax.set_ylim3d(np.min(y), np.max(y))
ax.set_zlim3d(min_altitude, max_altitude)
答案 0 :(得分:0)
实际上,您不需要创建虚拟2D底图。如果将x和y刻度设置为子午线和平行线的数组,则python应正确标记底图。
将此代码改为:
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.basemap import Basemap
fig = plt.figure()
ax = fig.gca(projection='3d')
extent = [-180,180,-90,90]
bm = Basemap(llcrnrlon=extent[0], llcrnrlat=extent[2],
urcrnrlon=extent[1], urcrnrlat=extent[3],
projection='cyl', resolution='l', fix_aspect=False, ax=ax)
ax.add_collection3d(bm.drawcoastlines(linewidth=0.25))
ax.add_collection3d(bm.drawcountries(linewidth=0.35))
ax.view_init(azim = 230, elev = 50)
ax.set_xlabel(u'Longitude (°E)', labelpad=10)
ax.set_ylabel(u'Latitude (°N)', labelpad=10)
ax.set_zlabel(u'Altitude (ft)', labelpad=20)
# Add meridian and parallel gridlines
lon_step = 30
lat_step = 30
meridians = np.arange(extent[0], extent[1]+lon_step, lon_step)
parallels = np.arange(extent[2], extent[3]+lat_step, lat_step)
ax.set_yticks(parallels)
ax.set_yticklabels(parallels)
ax.set_xticks(meridians)
ax.set_xticklabels(meridians)
ax.set_zlim(0., 40000.)
plt.show()