【问题标题】:Showing Alaska and Hawaii in Cartopy map在 Cartopy 地图中显示阿拉斯加和夏威夷
【发布时间】:2019-04-09 17:31:41
【问题描述】:

以下代码创建了一张美国大陆各州的地图,该地图以人口密度为阴影。我想创建一个类似的地图(我的数据实际上不是人口密度,但这是一个简单的例子),除了它还包括阿拉斯加州和夏威夷州。

具体来说,我想让阿拉斯加/夏威夷出现在图中,但要移动到显示美国大陆的图中部分下方。或者类似的东西。

知道如何使用 Cartopy 创建这样的地图吗?

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.LambertConformal())

ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic())

shapename = 'admin_1_states_provinces_lakes_shp'
states_shp = shpreader.natural_earth(resolution='110m',
                                     category='cultural', name=shapename)

popdensity = {
    'New Jersey':  438.00,
    'Rhode Island':   387.35,
    'Massachusetts':   312.68,
    'Connecticut':    271.40,
    'Maryland':   209.23,
    'New York':    155.18,
    'Delaware':    154.87,
    'Florida':     114.43,
    'Ohio':  107.05,
    'Pennsylvania':  105.80,
    'Illinois':    86.27,
    'California':  83.85,
    'Virginia':    69.03,
    'Michigan':    67.55,
    'Indiana':    65.46,
    'North Carolina':  63.80,
    'Georgia':     54.59,
    'Tennessee':   53.29,
    'New Hampshire':   53.20,
    'South Carolina':  51.45,
    'Louisiana':   39.61,
    'Kentucky':   39.28,
    'Wisconsin':  38.13,
    'Washington':  34.20,
    'Alabama':     33.84,
    'Missouri':    31.36,
    'Texas':   30.75,
    'West Virginia':   29.00,
    'Vermont':     25.41,
    'Minnesota':  23.86,
    'Mississippi':   23.42,
    'Iowa':  20.22,
    'Arkansas':    19.82,
    'Oklahoma':    19.40,
    'Arizona':     17.43,
    'Colorado':    16.01,
    'Maine':  15.95,
    'Oregon':  13.76,
    'Kansas':  12.69,
    'Utah':  10.50,
    'Nebraska':    8.60,
    'Nevada':  7.03,
    'Idaho':   6.04,
    'New Mexico':  5.79,
    'South Dakota':  3.84,
    'North Dakota':  3.59,
    'Montana':     2.39,
    'Wyoming':      1.96}

ax.background_patch.set_visible(False)
ax.outline_patch.set_visible(False)

ax.set_title('State Population Density')

for state in shpreader.Reader(states_shp).records():

    edgecolor = 'black'

    try:
        # use the name of this state to get pop_density
        state_dens = popdensity[ state.attributes['name'] ]
    except:
        state_dens = 0

    # simple scheme to assign color to each state
    if state_dens < 40:
        facecolor = "lightyellow"
    elif state_dens > 200:
        facecolor = "red"
    else:
        facecolor = "pink"

    # `state.geometry` is the polygon to plot
    ax.add_geometries([state.geometry], ccrs.PlateCarree(),
                      facecolor=facecolor, edgecolor=edgecolor)

plt.show()

这个(当前)创建的图如下:

【问题讨论】:

    标签: matplotlib cartopy


    【解决方案1】:

    将插图作为主地图的一部分进行绘制具有挑战性。您将需要创建一个axes 来绘制每个插图,并将其放置在figure 上的适当位置和相对比例。这是一个您可以试验的工作代码。

    import matplotlib.pyplot as plt
    import cartopy
    import cartopy.crs as ccrs
    import cartopy.io.shapereader as shpreader
    
    import shapely.geometry as sgeom
    
    # A function that draws inset map, ++
    # ===================================
    def add_insetmap(axes_extent, map_extent, state_name, facecolor, edgecolor, geometry):
        # create new axes, set its projection
        use_projection = ccrs.Mercator()     # preserve shape well
        #use_projection = ccrs.PlateCarree()   # large distortion in E-W for Alaska
        geodetic = ccrs.Geodetic(globe=ccrs.Globe(datum='WGS84'))
        sub_ax = plt.axes(axes_extent, projection=use_projection)  # normal units
        sub_ax.set_extent(map_extent, geodetic)  # map extents
    
        # add basic land, coastlines of the map
        # you may comment out if you don't need them
        sub_ax.add_feature(cartopy.feature.LAND)
        sub_ax.coastlines()
    
        sub_ax.set_title(state_name)
    
        # add map `geometry` here
        sub_ax.add_geometries([geometry], ccrs.PlateCarree(), \
                              facecolor=facecolor, edgecolor=edgecolor)
        # +++ more features can be added here +++
    
        # plot box around the map
        extent_box = sgeom.box(map_extent[0], map_extent[2], map_extent[1], map_extent[3])
        sub_ax.add_geometries([extent_box], ccrs.PlateCarree(), color='none', linewidth=0.05)
    
    
    fig = plt.figure()
    ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.LambertConformal())
    
    ax.set_extent([-125, -66.5, 20, 50], ccrs.Geodetic())
    
    shapename = 'admin_1_states_provinces_lakes_shp'
    states_shp = shpreader.natural_earth(resolution='110m',
                                         category='cultural', name=shapename)
    
    popdensity = {
        'New Jersey':  438.00,
        'Rhode Island':   387.35,
        'Massachusetts':   312.68,
        'Connecticut':    271.40,
        'Maryland':   209.23,
        'New York':    155.18,
        'Delaware':    154.87,
        'Florida':     114.43,
        'Ohio':  107.05,
        'Pennsylvania':  105.80,
        'Illinois':    86.27,
        'California':  83.85,
        'Virginia':    69.03,
        'Michigan':    67.55,
        'Indiana':    65.46,
        'North Carolina':  63.80,
        'Georgia':     54.59,
        'Tennessee':   53.29,
        'New Hampshire':   53.20,
        'South Carolina':  51.45,
        'Louisiana':   39.61,
        'Kentucky':   39.28,
        'Wisconsin':  38.13,
        'Washington':  34.20,
        'Alabama':     33.84,
        'Missouri':    31.36,
        'Texas':   30.75,
        'West Virginia':   29.00,
        'Vermont':     25.41,
        'Minnesota':  23.86,
        'Mississippi':   23.42,
        'Iowa':  20.22,
        'Arkansas':    19.82,
        'Oklahoma':    19.40,
        'Arizona':     17.43,
        'Colorado':    16.01,
        'Maine':  15.95,
        'Oregon':  13.76,
        'Kansas':  12.69,
        'Utah':  10.50,
        'Nebraska':    8.60,
        'Nevada':  7.03,
        'Idaho':   6.04,
        'New Mexico':  5.79,
        'South Dakota':  3.84,
        'North Dakota':  3.59,
        'Montana':     2.39,
        'Wyoming':      1.96}
    
    ax.background_patch.set_visible(False)
    ax.outline_patch.set_visible(False)
    
    ax.set_title('State Population Density')
    
    for state in shpreader.Reader(states_shp).records():
    
    
        edgecolor = 'black'
    
        try:
            # use the name of this state to get pop_density
            state_dens = popdensity[ state.attributes['name'] ]
        except:
            state_dens = 0
    
        # simple scheme to assign color to each state
        if state_dens < 40:
            facecolor = "lightyellow"
        elif state_dens > 200:
            facecolor = "red"
        else:
            facecolor = "pink"
    
        # special handling for the 2 states
        # ---------------------------------
        if state.attributes['name'] in ("Alaska", "Hawaii"):
            # print("state.attributes['name']:", state.attributes['name'])
    
            state_name = state.attributes['name']
    
            # prep map settings
            # experiment with the numbers in both `_extents` for your best results
            if state_name == "Alaska":
                # (1) Alaska
                map_extent = (-178, -135, 46, 73)    # degrees: (lonmin,lonmax,latmin,latmax)
                axes_extent = (0.04, 0.06, 0.29, 0.275) # axes units: 0 to 1, (LLx,LLy,width,height)
    
            if state_name == "Hawaii":
                # (2) Hawii
                map_extent = (-162, -152, 15, 25)
                axes_extent = (0.27, 0.06, 0.15, 0.15)
    
            # add inset maps
            add_insetmap(axes_extent, map_extent, state_name, \
                         facecolor, \
                         edgecolor, \
                         state.geometry)
    
        # the other (conterminous) states go here
        else:
            # `state.geometry` is the polygon to plot
            ax.add_geometries([state.geometry], ccrs.PlateCarree(),
                              facecolor=facecolor, edgecolor=edgecolor)
    
    plt.show()
    

    输出图将是:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 2022-01-10
      相关资源
      最近更新 更多