{"id":206,"date":"2009-01-17T13:47:11","date_gmt":"2009-01-17T17:47:11","guid":{"rendered":"http:\/\/metcaffeination.net\/weblog\/?p=206"},"modified":"2009-01-17T13:48:40","modified_gmt":"2009-01-17T17:48:40","slug":"red-street-blue-street","status":"publish","type":"post","link":"https:\/\/metcaffeination.net\/weblog\/2009\/01\/17\/red-street-blue-street\/","title":{"rendered":"Red Street, Blue Street"},"content":{"rendered":"<p>In the end, I went with the upgrade to <a href=\"http:\/\/wolfram.com\/products\/mathematica\/index.html\">Mathematica 7<\/a>. Of all the new features, the one that really hooked me&#8211;which is comparatively minor, compared to all the other new features&#8211;is the ability to import SHP files. The importation is not terribly well documented nor is there much additional support, but it was pretty easy to do a few nifty things with the  <a href=\"http:\/\/data.octo.dc.gov\/Metadata.aspx?id=122\">DC Street Centerline<\/a> file.<\/p>\n<p>As you may know, there is a street in DC for every state in the union. Pennsylvania Avenue is probably the most famous of these; the White House sits at 1600 Pennsylvania Ave NW. I used to live on Massachusetts Avenue. So my first idea was to make a street map of DC in which the state-named streets were colored red-ish or blue-ish depending on their vote in the recent election.<\/p>\n<p>Here it is:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-208\" title=\"redbluestreet_1\" usemap=\"#map_1\" src=\"http:\/\/metcaffeination.net\/weblog\/wp-content\/uploads\/2009\/01\/redbluestreet_1.gif\" alt=\"\" width=\"400\" height=\"495\" srcset=\"https:\/\/metcaffeination.net\/weblog\/wp-content\/uploads\/2009\/01\/redbluestreet_1.gif 400w, https:\/\/metcaffeination.net\/weblog\/wp-content\/uploads\/2009\/01\/redbluestreet_1-242x300.gif 242w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<map name='map_1'>\n<area shape='rect' coords='118,197,150,185' title='WYOMING' nohref \/>\n<area shape='rect' coords='62,232,111,84' title='WISCONSIN' nohref \/>\n<area shape='rect' coords='229,231,267,190' title='WEST VIRGINIA' nohref \/>\n<area shape='rect' coords='101,368,238,179' title='WASHINGTON' nohref \/>\n<area shape='rect' coords='114,289,238,228' title='VIRGINIA' nohref \/>\n<area shape='rect' coords='155,236,182,187' title='VERMONT' nohref \/>\n<area shape='rect' coords='98,86,122,51' title='UTAH' nohref \/>\n<area shape='rect' coords='278,313,341,254' title='TEXAS' nohref \/>\n<area shape='rect' coords='239,259,257,236' title='TENNESSEE' nohref \/>\n<area shape='rect' coords='205,194,311,87' title='SOUTH DAKOTA' nohref \/>\n<area shape='rect' coords='214,279,257,260' title='SOUTH CAROLINA' nohref \/>\n<area shape='rect' coords='144,223,295,146' title='RHODE ISLAND' nohref \/>\n<area shape='rect' coords='113,323,326,218' title='PENNSYLVANIA' nohref \/>\n<area shape='rect' coords='120,91,131,28' title='OREGON' nohref \/>\n<area shape='rect' coords='266,251,283,236' title='OKLAHOMA' nohref \/>\n<area shape='rect' coords='118,335,186,249' title='OHIO' nohref \/>\n<area shape='rect' coords='190,89,207,74' title='NORTH DAKOTA' nohref \/>\n<area shape='rect' coords='208,276,261,246' title='NORTH CAROLINA' nohref \/>\n<area shape='rect' coords='143,246,335,185' title='NEW YORK' nohref \/>\n<area shape='rect' coords='58,175,76,146' title='NEW MEXICO' nohref \/>\n<area shape='rect' coords='187,296,220,195' title='NEW JERSEY' nohref \/>\n<area shape='rect' coords='119,243,223,74' title='NEW HAMPSHIRE' nohref \/>\n<area shape='rect' coords='85,98,106,62' title='NEVADA' nohref \/>\n<area shape='rect' coords='33,188,127,63' title='NEBRASKA' nohref \/>\n<area shape='rect' coords='221,203,273,170' title='MONTANA' nohref \/>\n<area shape='rect' coords='147,107,210,82' title='MISSOURI' nohref \/>\n<area shape='rect' coords='206,399,278,363' title='MISSISSIPPI' nohref \/>\n<area shape='rect' coords='249,316,354,206' title='MINNESOTA' nohref \/>\n<area shape='rect' coords='182,174,268,120' title='MICHIGAN' nohref \/>\n<area shape='rect' coords='34,309,338,115' title='MASSACHUSETTS' nohref \/>\n<area shape='rect' coords='164,275,282,217' title='MARYLAND' nohref \/>\n<area shape='rect' coords='151,292,190,259' title='MAINE' nohref \/>\n<area shape='rect' coords='196,255,213,239' title='LOUISIANA' nohref \/>\n<area shape='rect' coords='239,286,261,256' title='KENTUCKY' nohref \/>\n<area shape='rect' coords='165,151,216,67' title='KANSAS' nohref \/>\n<area shape='rect' coords='155,135,179,107' title='IOWA' nohref \/>\n<area shape='rect' coords='180,252,205,242' title='INDIANA' nohref \/>\n<area shape='rect' coords='168,145,196,96' title='ILLINOIS' nohref \/>\n<area shape='rect' coords='75,167,96,132' title='IDAHO' nohref \/>\n<area shape='rect' coords='204,140,227,119' title='HAWAII' nohref \/>\n<area shape='rect' coords='168,198,187,29' title='GEORGIA' nohref \/>\n<area shape='rect' coords='129,236,256,181' title='FLORIDA' nohref \/>\n<area shape='rect' coords='193,300,221,217' title='DELAWARE' nohref \/>\n<area shape='rect' coords='78,236,157,71' title='CONNECTICUT' nohref \/>\n<area shape='rect' coords='136,133,174,85' title='COLORADO' nohref \/>\n<area shape='rect' coords='118,200,152,187' title='CALIFORNIA' nohref \/>\n<area shape='rect' coords='153,144,176,108' title='ARKANSAS' nohref \/>\n<area shape='rect' coords='21,178,47,153' title='ARIZONA' nohref \/>\n<area shape='rect' coords='153,59,177,30' title='ALASKA' nohref \/>\n<area shape='rect' coords='220,371,344,270' title='ALABAMA' nohref \/>\n<\/map>\n<p>Read on to see how I made it:<\/p>\n<p><!--more--><\/p>\n<p>I imported election returns from <a href=\"http:\/\/en.wikipedia.org\/wiki\/United_States_presidential_election,_2008\">Wikipedia<\/a>, but the process of picking the data I wanted out of the whole <code>Import<\/code> was so ugly that I&#8217;m not going to step through it here. I was inspired, though, by <a href=\"http:\/\/blog.wolfram.com\/2008\/09\/24\/analyzing-us-2008-elections-with-mathematica\/\">this similar post<\/a> on the Wolfram blog. If anyone at Wolfram is listening: it&#8217;d be really great if we could import data from the web by, say, clicking on a table of a web page displayed in a browser, instead of picking out which item in some nested list is the one we want.<\/p>\n<p>From the raw vote data, I computed the (approximate) percentage of the vote that Obama got:<sup><a href=\"#footnote_0_206\" id=\"identifier_0_206\" class=\"footnote-link footnote-identifier-link\" title=\"really, it&rsquo;s Obama&rsquo;s percentage of the combined Obama\/ McCain vote, ignoring votes for other candidates\">1<\/a><\/sup><br \/>\n<code><br \/>\nntrs[x_] := N[ToExpression[StringReplace[x, \",\" -&gt; \"\"]]]<br \/>\npercentData = {ToUpperCase[#[[1]]], ntrs[#[[2]]]\/(ntrs[#[[2]]] + ntrs[#[[3]]])} &amp; \/@ votedata<br \/>\n<\/code><br \/>\nWhich gives a list of things like<br \/>\n<code><br \/>\n{\"CALIFORNIA\", 0.622799}<\/code>.<br \/>\nThe conversion to uppercase is to match the way the DC street names are recorded.<\/p>\n<p>I&#8217;ll need a list of states, in order to match the street names. I get this from Mathematica&#8217;s curated <code>CountryData<\/code> data set, using a Regular Expression to insert a space any time there&#8217;s a lowercase letter followed by an uppercase letter, to change, for example, &#8220;NewJersey&#8221; into &#8220;New Jersey&#8221;:<br \/>\n<code><br \/>\nstates = StringReplace[#,\u00a0RegularExpression[\"([a-z])([A-Z])\"] -&gt; \"$1 $2\"] &amp; \/@\u00a0CountryData[\"United States\", \"Regions\"]<br \/>\n<\/code><\/p>\n<p>And the street datafile itself. When Mathematica imports SHP files, it returns a list of layers; with only one layer in this file, we get a (long) list with one element. So I specify in the <code>Import<\/code> that I only want this first (and only) element of the list:<br \/>\n<code><br \/>\ndcstreets=Import[\"StreetSegmentsLn.shp\",\"Data\"][[1]];<br \/>\n<\/code><br \/>\nAnd this gives a list of 4 replacement rules, some of which are very long:<br \/>\n<code><br \/>\nIn[]:=dcstreets[[1]]<br \/>\nOut[]:=LayerName -&gt; StreetSegmentLn<br \/>\nIn[]:=dcstreets[[2]]<br \/>\nOut[]:=Geometry -&gt; <em>long list of graphics primitives defining the data elements<\/em><br \/>\nIn[]:=dcstreets[[3]]<br \/>\nOut[]:=Labels -&gt; <em>list of the names of metadata fields<\/em><br \/>\nIn[]:=dcstreets[[4]]<br \/>\nOut[]:=LabeledData -&gt; <em>list of (long) lists of metadata for each data element<\/em><br \/>\n<\/code><br \/>\nFor this data file, the data elements are segments of streets between intersections, so the graphics primitives are lines defined by two (or more, for curved streets) points. There are 25 metadata fields, including the name of each street, the address range covered by the segment, the quadrant, and the type of road (e.g. Local, Principal Arterial, etc.). The <code>FullForm<\/code> of Mathematica replacement rule, such as <code>lhs -&gt; rhs<\/code>, is <code>Rule[lhs,rhs]<\/code>, so we access the data in each of the four rules as the second element of another list. Thus we can get at, say, the graphics primitives for the 27th street segment as<br \/>\n<code><br \/>\nIn[]:=dcstreets[[2,2,27]]<br \/>\nOut[]:=Line[{{396233., 138045.}, {396233., 138132.}, {396233., 138142.}}]<br \/>\n<\/code><br \/>\nFor ease in working with these data, I combined the geometry and metadata into one table for the 13414 street segments:<br \/>\n<code><br \/>\ndcstreetdata =\u00a0Transpose[Join[{dcstreets[[2, 2]]}, dcstreets[[4, 2, All, 2]]]];<br \/>\n<\/code><br \/>\nI separate this into two groups: state-named streets, and the rest:<br \/>\n<code><br \/>\nstatestreets =\u00a0Select[dcstreetdata, MemberQ[ToUpperCase[states], #[[6]]] &amp;];<br \/>\nnonstatestreets =\u00a0Select[dcstreetdata, ! MemberQ[ToUpperCase[states], #[[6]]] &amp;];<br \/>\n<\/code><br \/>\nThe 6th element of each entry in <code>dcstreetdata<\/code> is the name of the street. From this, I create two graphics:<br \/>\n<code><br \/>\nnonstatemap = Graphics[{Gray, nonstatestreets[[All, 1]]}]<\/code><\/p>\n<p><code><br \/>\nstatemap =\u00a0Graphics[Function[x,\u00a0Tooltip[{Directive[Thick,\u00a0RGBColor[.5 + 2 (.5 - x[[2]]), 0, .5 + 2 (x[[2]] - .5)]],\u00a0Transpose[Select[statestreets, Function[y, y[[6]] == x[[1]]]]][[1]]}, x[[1]]]] \/@ percentData]<br \/>\n<\/code><br \/>\nI&#8217;ve packed a lot into statemap, using nested pure functions: it makes a Tooltip with the state\/street name popping up upon mouseover (it works better in Mathematica than in the export HTML). For each state from the list of election returns in <code>percentData<\/code>, it finds all the street segments named after that state and makes a graphic element out of the geometry of that street segment, of a color that ranges from pure blue to pure red. The red-blue divide is stretched so that pure blue corresponds to the percentage of Obama&#8217;s highest percentage (Hawaii, 72.99%) and pure red corresponds to Obama&#8217;s lowest percentage (Wyoming, 33.43%). The final map is created with <code>Show<\/code>:<br \/>\n<code><br \/>\nvotemap = Show[statemap, nonstatemap]<\/code><\/p>\n<p>So far, so good. I&#8217;ll write more on Mathematica and DC GIS data soon.<\/p>\n<ol class=\"footnotes\"><li id=\"footnote_0_206\" class=\"footnote\">really, it&#8217;s Obama&#8217;s percentage of the combined Obama\/ McCain vote, ignoring votes for other candidates [<a href=\"#identifier_0_206\" class=\"footnote-link footnote-back-link\">&#8617;<\/a>]<\/li><\/ol>","protected":false},"excerpt":{"rendered":"<p>In the end, I went with the upgrade to Mathematica 7. Of all the new features, the one that really hooked me&#8211;which is comparatively minor, compared to all the other new features&#8211;is the ability to import SHP files. The importation is not terribly well documented nor is there much additional support, but it was pretty [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,12,26],"tags":[],"class_list":["post-206","post","type-post","status-publish","format-standard","hentry","category-dc","category-doing-the-math","category-politics"],"_links":{"self":[{"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/posts\/206","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/comments?post=206"}],"version-history":[{"count":6,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/posts\/206\/revisions"}],"predecessor-version":[{"id":213,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/posts\/206\/revisions\/213"}],"wp:attachment":[{"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/media?parent=206"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/categories?post=206"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metcaffeination.net\/weblog\/wp-json\/wp\/v2\/tags?post=206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}