|
2 | 2 | import numpy as np
|
3 | 3 | import matplotlib.pyplot as plt
|
4 | 4 | from mpl_toolkits.basemap import Basemap as Basemap
|
5 |
| -from matplotlib.colors import rgb2hex |
| 5 | +from matplotlib.colors import rgb2hex, Normalize |
6 | 6 | from matplotlib.patches import Polygon
|
| 7 | +from matplotlib.colorbar import ColorbarBase |
| 8 | + |
| 9 | +fig, ax = plt.subplots() |
7 | 10 |
|
8 | 11 | # Lambert Conformal map of lower 48 states.
|
9 |
| -m = Basemap(llcrnrlon=-119,llcrnrlat=22,urcrnrlon=-64,urcrnrlat=49, |
| 12 | +m = Basemap(llcrnrlon=-119,llcrnrlat=20,urcrnrlon=-64,urcrnrlat=49, |
10 | 13 | projection='lcc',lat_1=33,lat_2=45,lon_0=-95)
|
11 |
| -# draw state boundaries. |
12 |
| -# data from U.S Census Bureau |
13 |
| -# http://www.census.gov/geo/www/cob/st2000.html |
14 |
| -shp_info = m.readshapefile('st99_d00','states',drawbounds=True) |
15 |
| -# population density by state from |
16 |
| -# http://en.wikipedia.org/wiki/List_of_U.S._states_by_population_density |
| 14 | + |
| 15 | +# Mercator projection, for Alaska and Hawaii |
| 16 | +m_ = Basemap(llcrnrlon=-190,llcrnrlat=20,urcrnrlon=-143,urcrnrlat=46, |
| 17 | + projection='merc',lat_ts=20) # do not change these numbers |
| 18 | + |
| 19 | +#%% --------- draw state boundaries ---------------------------------------- |
| 20 | +## data from U.S Census Bureau |
| 21 | +## http://www.census.gov/geo/www/cob/st2000.html |
| 22 | +shp_info = m.readshapefile('st99_d00','states',drawbounds=True, |
| 23 | + linewidth=0.45,color='gray') |
| 24 | +shp_info_ = m_.readshapefile('st99_d00','states',drawbounds=False) |
| 25 | + |
| 26 | +## population density by state from |
| 27 | +## http://en.wikipedia.org/wiki/List_of_U.S._states_by_population_density |
17 | 28 | popdensity = {
|
18 | 29 | 'New Jersey': 438.00,
|
19 | 30 | 'Rhode Island': 387.35,
|
|
65 | 76 | 'Montana': 2.39,
|
66 | 77 | 'Wyoming': 1.96,
|
67 | 78 | 'Alaska': 0.42}
|
68 |
| -print(shp_info) |
69 |
| -# choose a color for each state based on population density. |
| 79 | + |
| 80 | +#%% -------- choose a color for each state based on population density. ------- |
70 | 81 | colors={}
|
71 | 82 | statenames=[]
|
72 |
| -cmap = plt.cm.hot # use 'hot' colormap |
| 83 | +cmap = plt.cm.hot_r # use 'reversed hot' colormap |
73 | 84 | vmin = 0; vmax = 450 # set range.
|
74 |
| -print(m.states_info[0].keys()) |
| 85 | +norm = Normalize(vmin=vmin, vmax=vmax) |
75 | 86 | for shapedict in m.states_info:
|
76 | 87 | statename = shapedict['NAME']
|
77 | 88 | # skip DC and Puerto Rico.
|
|
80 | 91 | # calling colormap with value between 0 and 1 returns
|
81 | 92 | # rgba value. Invert color range (hot colors are high
|
82 | 93 | # population), take sqrt root to spread out colors more.
|
83 |
| - colors[statename] = cmap(1.-np.sqrt((pop-vmin)/(vmax-vmin)))[:3] |
| 94 | + colors[statename] = cmap(np.sqrt((pop-vmin)/(vmax-vmin)))[:3] |
84 | 95 | statenames.append(statename)
|
85 |
| -# cycle through state names, color each one. |
86 |
| -ax = plt.gca() # get current axes instance |
| 96 | + |
| 97 | +#%% --------- cycle through state names, color each one. -------------------- |
87 | 98 | for nshape,seg in enumerate(m.states):
|
88 | 99 | # skip DC and Puerto Rico.
|
89 |
| - if statenames[nshape] not in ['District of Columbia','Puerto Rico']: |
90 |
| - color = rgb2hex(colors[statenames[nshape]]) |
| 100 | + if statenames[nshape] not in ['Puerto Rico', 'District of Columbia']: |
| 101 | + color = rgb2hex(colors[statenames[nshape]]) |
91 | 102 | poly = Polygon(seg,facecolor=color,edgecolor=color)
|
92 | 103 | ax.add_patch(poly)
|
93 |
| -# draw meridians and parallels. |
94 |
| -m.drawparallels(np.arange(25,65,20),labels=[1,0,0,0]) |
95 |
| -m.drawmeridians(np.arange(-120,-40,20),labels=[0,0,0,1]) |
96 |
| -plt.title('Filling State Polygons by Population Density') |
| 104 | + |
| 105 | +AREA_1 = 0.005 # exclude small Hawaiian islands that are smaller than AREA_1 |
| 106 | +AREA_2 = AREA_1 * 30.0 # exclude Alaskan islands that are smaller than AREA_2 |
| 107 | +AK_SCALE = 0.19 # scale down Alaska to show as a map inset |
| 108 | +HI_OFFSET_X = -1900000 # X coordinate offset amount to move Hawaii "beneath" Texas |
| 109 | +HI_OFFSET_Y = 250000 # similar to above: Y offset for Hawaii |
| 110 | +AK_OFFSET_X = -250000 # X offset for Alaska (These four values are obtained |
| 111 | +AK_OFFSET_Y = -750000 # via manual trial and error, thus changing them is not recommended.) |
| 112 | + |
| 113 | +for nshape, shapedict in enumerate(m_.states_info): # plot Alaska and Hawaii as map insets |
| 114 | + if shapedict['NAME'] in ['Alaska', 'Hawaii']: |
| 115 | + seg = m_.states[int(shapedict['SHAPENUM'] - 1)] |
| 116 | + if shapedict['NAME'] == 'Hawaii' and float(shapedict['AREA']) > AREA_1: |
| 117 | + seg = [(x + HI_OFFSET_X, y + HI_OFFSET_Y) for x, y in seg] |
| 118 | + color = rgb2hex(colors[statenames[nshape]]) |
| 119 | + elif shapedict['NAME'] == 'Alaska' and float(shapedict['AREA']) > AREA_2: |
| 120 | + seg = [(x*AK_SCALE + AK_OFFSET_X, y*AK_SCALE + AK_OFFSET_Y)\ |
| 121 | + for x, y in seg] |
| 122 | + color = rgb2hex(colors[statenames[nshape]]) |
| 123 | + poly = Polygon(seg, facecolor=color, edgecolor='gray', linewidth=.45) |
| 124 | + ax.add_patch(poly) |
| 125 | + |
| 126 | +ax.set_title('United states population density by state') |
| 127 | + |
| 128 | +#%% --------- Plot bounding boxes for Alaska and Hawaii insets -------------- |
| 129 | +light_gray = [0.8]*3 # define light gray color RGB |
| 130 | +x1,y1 = m_([-190,-183,-180,-180,-175,-171,-171],[29,29,26,26,26,22,20]) |
| 131 | +x2,y2 = m_([-180,-180,-177],[26,23,20]) # these numbers are fine-tuned manually |
| 132 | +m_.plot(x1,y1,color=light_gray,linewidth=0.8) # do not change them drastically |
| 133 | +m_.plot(x2,y2,color=light_gray,linewidth=0.8) |
| 134 | + |
| 135 | +#%% --------- Show color bar --------------------------------------- |
| 136 | +ax_c = fig.add_axes([0.9, 0.1, 0.03, 0.8]) |
| 137 | +cb = ColorbarBase(ax_c,cmap=cmap,norm=norm,orientation='vertical', |
| 138 | + label=r'[population per $\mathregular{km^2}$]') |
| 139 | + |
97 | 140 | plt.show()
|
| 141 | + |
0 commit comments