【发布时间】:2015-11-12 21:09:41
【问题描述】:
我正在尝试在 Python 中生成一个将显示(除其他外)的图形:
A) 从墨卡托投影图像转换的底图
B) 带标签的网格线
我希望人物处于横向墨卡托(或其他球面)投影中。
我已经尝试过 Matplotlib 底图和 Cartopy。 Cartopy 可以做(A),Basemap 可以做(B),但是 Cartopy 只能在 PlateCarree 图上标注网格线,而且 Basemap 不支持使用imshow() 转换图像。
除非有人可以提出其他替代方案,否则我认为解决此问题的最简单方法是在重新投影的图像上覆盖 Basemap 图中的网格线和标签。但是我无法让这两个情节相互对齐。到目前为止我所拥有的:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import cartopy.crs as ccrs
#Setup figure
fig = plt.figure(figsize=(20, 20))
#Set figure limits (lat long)
xlimits = [25, 42]
ylimits = [25, 40]
#Where the projection is centred
centre = [33, 33]
#Image limits in Mercator Eastings and Northings
imxlimits = [25, 42]
imylimits = [25, 40]
#Transform image Limits
imextent = tuple(ccrs.Mercator().transform_points(ccrs.Geodetic(),
np.array(imxlimits), np.array(imylimits))[:, 0:2].T.flatten())
#Load image
image = plt.imread(Dir + 'topo.png')
tm = ccrs.TransverseMercator(central_longitude=centre[0], central_latitude=centre[1])
ll = ccrs.Geodetic()
#Setup image axies
ax = fig.add_subplot(111, projection=tm)
ax.set_extent(xlimits + ylimits, ll) #<--Limits defined here
#Plot image transformed
ax.imshow(image, origin='upper', extent=imextent, transform=ccrs.Mercator())
#Create axes for gridlines
axl = fig.add_subplot(111)
#Make the figure background transparent
axl.patch.set_alpha(0)
#Make basemap instance
m = Basemap(projection='tmerc', resolution='h', ax=axl,
lat_0=centre[1], lon_0=centre[0],
llcrnrlon=xlimits[0], llcrnrlat=ylimits[0], #<--Limits defined here
urcrnrlon=xlimits[1], urcrnrlat=ylimits[1])
m.drawcoastlines() #to check if the images match up
#Draw gridlines
m.drawparallels(np.arange(20, 50), labels=[False, True, False, False])
m.drawmeridians(np.arange(20, 50), labels=[False, False, False, True])
plt.show()
这会产生大致彼此重叠但不匹配的图。我认为这是因为为第一个图给出的限制可能是针对顶部和底部边缘设置的,而为第二个图给出的(相同)限制是针对右上角和左下角的。
关于如何解决此问题的任何提示?
谢谢!
【问题讨论】:
-
好问题!也许添加一个cartopy标签?我在将 MPL.Basemap 投影与其他数据对齐时也遇到了问题。我一直认为我没有选择正确的球体或投影参数是我的错误,但我开始觉得 Basemap 在这个部门有一些错误(例如this)。
-
好的,很高兴听到不仅仅是我有问题。我猜他们可能正在使用不同的方法来转换为轴坐标。
标签: python matplotlib matplotlib-basemap cartopy