Skip to content

Commit 140f9fe

Browse files
authored
Merge pull request #366 from jsh9/update-fillstates-example
Updated fillstates.py to add Alaska and Hawaii as map insets
2 parents 27d6bbb + cfff23e commit 140f9fe

File tree

1 file changed

+65
-21
lines changed

1 file changed

+65
-21
lines changed

examples/fillstates.py

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,29 @@
22
import numpy as np
33
import matplotlib.pyplot as plt
44
from mpl_toolkits.basemap import Basemap as Basemap
5-
from matplotlib.colors import rgb2hex
5+
from matplotlib.colors import rgb2hex, Normalize
66
from matplotlib.patches import Polygon
7+
from matplotlib.colorbar import ColorbarBase
8+
9+
fig, ax = plt.subplots()
710

811
# 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,
1013
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
1728
popdensity = {
1829
'New Jersey': 438.00,
1930
'Rhode Island': 387.35,
@@ -65,13 +76,13 @@
6576
'Montana': 2.39,
6677
'Wyoming': 1.96,
6778
'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. -------
7081
colors={}
7182
statenames=[]
72-
cmap = plt.cm.hot # use 'hot' colormap
83+
cmap = plt.cm.hot_r # use 'reversed hot' colormap
7384
vmin = 0; vmax = 450 # set range.
74-
print(m.states_info[0].keys())
85+
norm = Normalize(vmin=vmin, vmax=vmax)
7586
for shapedict in m.states_info:
7687
statename = shapedict['NAME']
7788
# skip DC and Puerto Rico.
@@ -80,18 +91,51 @@
8091
# calling colormap with value between 0 and 1 returns
8192
# rgba value. Invert color range (hot colors are high
8293
# 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]
8495
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. --------------------
8798
for nshape,seg in enumerate(m.states):
8899
# 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]])
91102
poly = Polygon(seg,facecolor=color,edgecolor=color)
92103
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+
97140
plt.show()
141+

0 commit comments

Comments
 (0)