{smcl} {* *! version 1.0.0 31jan2017}{...} {cmd:help geo2xy_fun_with_maps} {hline} {title:Title} {phang} {bf:geo2xy} {hline 2} Fun with maps {pstd} This help file contains additional examples of how to produce maps with {cmd:geo2xy}. The examples require {cmd:geo2xy}'s ancillary datasets in the current directory. Click {stata `"net get geo2xy, from("http://fmwww.bc.edu/repec/bocode/g")"':here} to download them. {marker world_wiki}{...} {title:An Albers projection of the world} {pstd} The following example replicates the map of the world included in the Wikipedia entry for the {it:{browse "https://en.wikipedia.org/wiki/Albers_projection":Albers projection}}. The projected map was generated using standard parallels of 20 degrees north and 50 degrees north. The map does not include Antarctica. {pstd} The first step is to create a polygon that will cover the coordinate bounds of the world map. This is drawn first and filled with blue. With all country boundaries overlaid, the areas that are not covered depict the oceans and lakes of the world. {pstd} The four line segments that form the map's base polygon (coordinate bounds) need to include intermediary points because the projection will distort the position of points along the line segments. In the example below, each side of the map is defined using 100 points. Note that a polygon starts with a missing point, followed by a series of points. The last point closes the loop and has the same coordinates as the start point. This base polygon is given an identifier of 0 so as to not conflict with the range of values for {cmd:_ID} in the shapefile's coordinates dataset. {pstd} The next step is to create the map's graticule (major coordinate grid). The Wikipedia map example depicts 23 meridians and 11 parallels. As with the base polygon, these 34 lines need to include intermediary points so that each line follows the computed distorsions of the {it:{help geo2xy_albers:albers}} projection. Each line is given a negative identifier to avoid conflicts with other polygons. Each line starts with missing coordinates. {pstd} The graticule lines are then combined with the map's base polygon and with the polygons that define the boundaries of countries. The polygon that represents Antarctica is dropped to match the target map. Then {cmd:geo2xy} is called to generate projected (x,y) coordinates. In order to specify the required standard parallels, all parameters must be provided. {pstd} The map is created by overlaying a series of Stata graphs. The base map (the polygon with {cmd:_ID == 0}) comes first. To color the area of the polygon, a {helpb twoway area:[G-2] graph twoway area} plot is used with a suitable bluish fill color. {pstd} The next plot overlays all the country boundary polygons at once (all these have {cmd:_ID > 0}). Since these polygons are also to be filled, another {helpb twoway area:[G-2] graph twoway area} plot is used with a greenish color palette. {pstd} For Antarctica and Greenland (whose {cmd:_ID} are 7 and 66 respectively), we color the area in light gray since these are mostly covered in ice. {pstd} Continuing to build up the graph, all graticule line segments are plotted using a {helpb twoway line:[G-2] graph twoway line} plot. These are all identified using a negative value for {cmd:_ID}. {pstd} Finally, a couple of {cmd:line} plots are overlaid to highlight the prime meridian (in dark gray) and the equator (in maroon). The remaining options handle the overall appearance of the graph. {space 8}{hline 27} {it:example do-file content} {hline 27} {cmd}{...} {* example_start - fun_albers_world}{...} // create a polygon for the coordinate bounds of the map clear input order double(lat lon) 1 . . 2 90 -180 3 90 180 4 -90 180 5 -90 -180 6 90 -180 end gen double next_lat = lat[_n+1] gen double next_lon = lon[_n+1] expand 100 if !mi(lat, next_lat) bysort order: gen double _Y = lat + (next_lat - lat) / 100 * (_n-1) bysort order: gen double _X = lon + (next_lon - lon) / 100 * (_n-1) gen _ID = 0 tempfile bounds save "`bounds'" // create 23 meridians and 11 parallels, 34 lines in total clear set obs 34 gen _ID = -_n gen double _Y = -90 + (180 / 12) * _n if _ID > -12 gen double _X = -180 + (360 / 24) * (_n-11) if _ID <= -12 expand 102 bysort _ID: replace _Y = -90 + 180/100 * (_n-2) if mi(_Y) by _ID: replace _X = -180 + 360/100 * (_n-2) if mi(_X) by _ID: replace _Y = . if _n == 1 by _ID: replace _X = . if _n == 1 // combine the graticules with the base polygon and the country boundaries append using "`bounds'" append using "geo2xy_world_coor.dta" geo2xy _Y _X , gen(ylat xlon) proj(albers, 6378137 298.257223563 20 50 0 0) return list local yheight = 6 * `r(aspect)' twoway area ylat xlon if _ID == 0, color("20 120 160") nodropbase /// || /// area ylat xlon if _ID > 0, lwidth(vthin) lcolor(mint) color("20 70 40") /// cmissing(n) nodropbase /// || /// area ylat xlon if inlist(_ID,7,66), lwidth(vthin) lcolor(gs14) color(gs14) /// cmissing(n) nodropbase /// || /// line ylat xlon if _ID < 0, lwidth(vthin) lcolor(gs10) cmissing(n) /// || /// line ylat xlon if _ID == -6, lwidth(vthin) lcolor(maroon) /// || /// line ylat xlon if _ID == -23, lwidth(vthin) lcolor(gs4) /// xsize(6) ysize(`yheight') /// ylabel(minmax, nogrid) yscale(off) /// xlabel(minmax, nogrid) xscale(off) /// plotregion(margin(small)) graphregion(margin(small)) /// legend(off) name(fun_albers_world) {* example_end}{...} {txt}{...} {space 8}{hline 80} {space 8}{it:({stata geo2xy_run fun_albers_world using geo2xy_fun_with_maps.hlp, requires("geo2xy_world_coor.dta") preserve:click to run})} {marker composite_us}{...} {title:A composite map of the 48 conterminous states with Alaska and Hawaii} {pstd} The following example creates a map of the U.S.A. using a shapefile that is distributed with {cmd:geo2xy}. Requires {cmd:spmap} (from SSC, {it:{stata ssc install spmap:click to install}}): {space 8}{hline 27} {it:example do-file content} {hline 27} {cmd}{...} {* example_start - fun_composite_all}{...} use "geo2xy_us_data.dta", clear spmap using "geo2xy_us_coor.dta", id(_ID) name(fun_composite_all, replace) {* example_end}{...} {txt}{...} {space 8}{hline 80} {space 8}{it:({stata geo2xy_run fun_composite_all using geo2xy_fun_with_maps.hlp, requires("geo2xy_us_data.dta geo2xy_us_coor.dta") preserve:click to run})} {pstd} To move Alaska, Hawaii, and Puerto Rico closer to the 48 conterminous states, you could manipulate the geographic coordinates (latitude and longitude) directly but it's better to apply specific map projections first and then scale and move each map part to create a final map with a pleasant composition. {pstd} The example below uses an {it:{help geo2xy_albers:albers}} projection for all parts. The {it:{help geo2xy_albers:albers}} has the property that areas on the map are proportional to the same areas on the Earth. It is used by the USGS to represent the 48 conterminous states as well as for maps of Alaska and Hawaii. Note that both Hawaii and Alaska have islands on the other side of the International date line so we need to flip the longitudes to reconnect each side. The example implements the USGS-recommended standard parallels. To use these, all parameters must be specified. The central meridian is manually computed at mid-longitude. {space 8}{hline 27} {it:example do-file content} {hline 27} {cmd}{...} {* example_start - fun_composite}{...} use "geo2xy_us_coor.dta", clear // flip longitudes to reconnect Hawaii and Alaska replace _X = cond(_X > 0, _X - 180, _X + 180) if inlist(_ID, 14, 42) // Alaska - USGS recommends standard parallels of 55 and 65 north sum _X if _ID == 14 local midlon = (r(min) + r(max)) / 2 geo2xy _Y _X if _ID == 14, replace /// proj(albers, 6378137 298.257223563 55 65 0 `midlon') replace _Y = _Y / 3 + 800000 if _ID == 14 replace _X = _X / 3 - 1700000 if _ID == 14 // Hawaii - USGS recommends standard parallels of 8 and 18 north sum _X if _ID == 42 local midlon = (r(min) + r(max)) / 2 geo2xy _Y _X if _ID == 42, replace /// proj(albers, 6378137 298.257223563 8 18 0 `midlon') replace _Y = _Y / 1.2 + 850000 if _ID == 42 replace _X = _X / 1.2 - 800000 if _ID == 42 // Puerto Rico geo2xy _Y _X if _ID == 39, replace proj(albers) replace _Y = _Y + 500000 if _ID == 39 replace _X = _X + 2000000 if _ID == 39 // 48 states - USGS recommends standard parallels of 29.5 and 45.5 north sum _X if !inlist(_ID, 14, 42, 39) local midlon = (r(min) + r(max)) / 2 geo2xy _Y _X if !inlist(_ID, 14, 42, 39), replace /// proj(albers, 6378137 298.257223563 29.5 45.5 0 `midlon') save "xy_coor.dta", replace use "geo2xy_us_data.dta",clear spmap using "xy_coor.dta", id(_ID) name(fun_composite, replace) {* example_end}{...} {txt}{...} {space 8}{hline 80} {space 8}{it:({stata geo2xy_run fun_composite using geo2xy_fun_with_maps.hlp, requires("geo2xy_us_data.dta geo2xy_us_coor.dta") preserve:click to run})}