我该如何使用颜色图为Cartopy地图中的美国各州生成表示颜色值(例如人口密度)的面色?
下面的代码根据人口密度是<40、40和200之间还是> 200来分配颜色。我希望从GnBu matplotlib顺序色图中选择一种颜色。人口密度数据的(最小值,最大值)为(1.96,438.0),因此我将归一化为0到450。
我已经研究了一段时间,但只看到了在等高线图或类似图中使用颜色图的示例。我不确定如何适应这种应用程序,在这种应用程序中您必须从颜色图中提取单个值。
编辑:忘了提到它需要一个颜色条,将状态颜色映射到数值。
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()