绘制方形Cartopy地图

时间:2018-07-14 13:36:51

标签: python matplotlib cartopy

我需要使用Cartopy绘制正方形地图。我目前在地图上使用以下代码:

plt.figure(figsize = (15, 15))

img = cimgt.GoogleTiles()

ax = plt.axes(projection = img.crs)
ax.set_extent((d['longitude'].min() - 0.05, d['longitude'].max() + 0.05,
               d['latitude'].min() - 0.05, d['latitude'].max() + 0.05))

ax.add_image(img, 10, interpolation = 'bicubic')

plt.scatter(d['longitude'], d['latitude'], transform = ccrs.PlateCarree(),
            c = '#E8175D', s = 14)

这很好用,除了地图不是正方形。取而代之的是,它仅适合图的(15, 15)正方形。

enter image description here

我想在左侧和右侧添加更多的地图,以使绘图完全正方形而不变形。仅将范围设置为纬度和经度上的相同差异并不能解决问题,因为纬度和经度在Google(和大多数其他)地图投影中覆盖的距离不同。我还发现了this个帖子,但据我了解,这里的意图是使地图变形。

我希望有人对此有一个想法。似乎Cartopy在这方面不是很直观。

1 个答案:

答案 0 :(得分:2)

要获取平方范围,需要在地图投影坐标中指定它。这涉及一些坐标转换。这是您需要的代码段。

# crs of your choice
crg = cimgt.StamenTerrain().crs    # or cimgt.GoogleTiles().crs

# set map limits, in degrees
lonmin, lonmax = -22, -15
latmin, latmax = 63, 65

# do coordinate transformation
LL = crg.transform_point(lonmin, latmin, ccrs.Geodetic())
UR = crg.transform_point(lonmax, latmax, ccrs.Geodetic())
EW = UR[0] - LL[0]
SN = UR[1] - LL[1]

# get side of the square extent (in map units, usually meters)
side = max(EW, SN)    # larger value is in effect
mid_x, mid_y = LL[0]+EW/2.0, LL[1]+SN/2.0  # center location

# the extent preserves the center location
extent = [mid_x-side/2.0, mid_x+side/2.0, mid_y-side/2.0, mid_y+side/2.0]

# this sets square extent
# crs=crg signifies that projection coordinates is used in extent
ax.set_extent(extent, crs=crg)

希望有帮助。

修改

这是完整的工作代码及其生成的地图。

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.io.img_tiles as cimgt

def make_map(projection=ccrs.PlateCarree()):
    fig, ax = plt.subplots(figsize=(10, 10),
                           subplot_kw=dict(projection=projection))
    gl = ax.gridlines(draw_labels=True)
    gl.xlabels_top = gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    return fig, ax

request = cimgt.StamenTerrain()   # very responsive
crg = request.crs   #crs of the projection
fig, ax = make_map(projection = crg)

# specify map extent here
lonmin, lonmax = -22, -15
latmin, latmax = 63, 65

LL = crg.transform_point(lonmin, latmin, ccrs.Geodetic())
UR = crg.transform_point(lonmax, latmax, ccrs.Geodetic())
EW = UR[0] - LL[0]
SN = UR[1] - LL[1]
side = max(EW,SN)
mid_x, mid_y = LL[0]+EW/2.0, LL[1]+SN/2.0  #center location

extent = [mid_x-side/2.0, mid_x+side/2.0, mid_y-side/2.0, mid_y+side/2.0]   # map coordinates, meters

ax.set_extent(extent, crs=crg)
ax.add_image(request, 8)

# add a marker at center of the map
plt.plot(mid_x, mid_y, marker='o', \
         color='red', markersize=10, \
         alpha=0.7, transform = crg)

plt.show()

south of iceland