{"id":424,"date":"2014-01-06T21:36:30","date_gmt":"2014-01-07T02:36:30","guid":{"rendered":"http:\/\/homepages.uc.edu\/~yaozo\/wordpress\/?p=424"},"modified":"2014-01-06T21:36:30","modified_gmt":"2014-01-07T02:36:30","slug":"how-to-make-a-us-county-thematic-map-using-free-tools","status":"publish","type":"post","link":"https:\/\/zhuoyao.net\/index.php\/2014\/01\/06\/how-to-make-a-us-county-thematic-map-using-free-tools\/","title":{"rendered":"How to Make a US County Thematic Map Using Free Tools"},"content":{"rendered":"<div>\n<div>By\u00a0NATHAN YAU<\/div>\n<div id=\"lead-in\">\n<p><img decoding=\"async\" alt=\"Unemployment choropleth\" src=\"http:\/\/i1.wp.com\/flowingdata.com\/wp-content\/uploads\/2012\/01\/Unemployment-choropleth.png?fit=425%2C9999\" \/><\/p>\n<div>There are about a million ways to make a choropleth map. The problem is that a lot of solutions require expensive software or have a high learning curve. It doesn&#8217;t have to be that way.<\/div>\n<div id=\"tut-meta\">\n<div><a href=\"http:\/\/projects.flowingdata.com\/america\/unemployment\/\">Demo<\/a><\/div>\n<div><a href=\"http:\/\/projects.flowingdata.com\/tut\/200911-choropleth-tutorial.zip\">Download Source<\/a><\/div>\n<div><\/div>\n<\/div>\n<div><\/div>\n<\/div>\n<div>\n<p>What if you just want a simple map without all the GIS stuff? In this post, I&#8217;ll show you how to make a county-specific choropleth map using only free tools.<\/p>\n<p>Here&#8217;s\u00a0<a href=\"http:\/\/projects.flowingdata.com\/america\/unemployment\/\">what we&#8217;re after<\/a>. It&#8217;s an\u00a0<a href=\"http:\/\/flowingdata.com\/2009\/11\/04\/unemployment-2004-to-present-the-country-is-bleeding\/\">unemployment map<\/a>\u00a0from 2009.<\/p>\n<h3>Step 0. System requirements<\/h3>\n<p>This tutorial was written with Python 2.5 and Beautiful Soup 3. If you&#8217;re using a more recent version of either, you might have to modify the code. See comments below for tips.Just as a heads up, you&#8217;ll need\u00a0<a href=\"http:\/\/www.python.org\/\">Python<\/a>\u00a0installed on your computer. Python comes pre-installed on the Mac. I&#8217;m not sure about Windows. If you&#8217;re on Linux, well, I&#8217;m sure you&#8217;re a big enough nerd to already be fluent in Python.<\/p>\n<p>We&#8217;re going to make good use of the Python library\u00a0<a href=\"http:\/\/www.crummy.com\/software\/BeautifulSoup\/\">Beautiful Soup<\/a>, so you&#8217;ll need that too. It&#8217;s a super easy, super useful HTML\/XML parser that you should come to know and love.<\/p>\n<h3>Step 1. Prepare county-specific data<\/h3>\n<p>The first step of every visualization is to get the data. You can&#8217;t do anything without it. In this example we&#8217;re going to use county-level unemployment data from the Bureau of Labor Statistics. However, you have to go through FTP to get the most recent numbers, so to save some time,\u00a0<a href=\"http:\/\/datasets.flowingdata.com\/unemployment09.csv\">download the comma-separated (CSV) file here<\/a>.<\/p>\n<p>It was originally an Excel file. All I did was remove the headers and save as a CSV.<\/p>\n<h3>Step 2. Get the blank map<\/h3>\n<p>Luckily, we don&#8217;t have to start from scratch. We can get a blank\u00a0<a href=\"http:\/\/commons.wikimedia.org\/wiki\/File:USA_Counties_with_FIPS_and_names.svg\">USA counties map<\/a>\u00a0from Wikimedia Commons. The page links to the map in four sizes in PNG format and then one as SVG (<code>USA_Counties_with_FIPS_and_names.svg\u00e2\u20ac\u017d<\/code>). We want the SVG one. Download the SVG file onto your computer and save it as\u00a0<code>counties.svg<\/code>.<\/p>\n<p>Blank US counties map in SVG format<a href=\"http:\/\/commons.wikimedia.org\/wiki\/File:USA_Counties_with_FIPS_and_names.svg\"><img loading=\"lazy\" decoding=\"async\" title=\"usa-counties\" alt=\"usa-counties\" src=\"http:\/\/i2.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/usa-counties.png?resize=545%2C345\" width=\"545\" height=\"345\" \/><\/a><\/p>\n<p>The important thing here, if you&#8217;re not familiar with SVG (which stands for scalable vector graphics), is that it&#8217;s actually an XML file. It&#8217;s text with tags, and you can edit it in a text editor like you would a HTML file. The browser or image viewer reads the XML. The XML tells the browser what to show.<\/p>\n<p>Anyways, we&#8217;ve downloaded our SVG map. Let&#8217;s move on to the next step.<\/p>\n<h3>Step 3. Open the SVG file in a text editor<\/h3>\n<p>I want to make sure we&#8217;re clear on what we&#8217;re editing. Like I said in Step 2, our SVG map is simply an XML file. We&#8217;re not doing any photoshop or image-editing. We&#8217;re editing an XML file. Open up the SVG file in a text editor so that we can see what we&#8217;re dealing with.<\/p>\n<p>You should see\u00a0<a href=\"http:\/\/flowingdata.com\/?attachment_id=3611\">something like this<\/a>:<\/p>\n<p>SVG is just XML that you can change in a text editor.<img loading=\"lazy\" decoding=\"async\" title=\"svg-shot-top\" alt=\"svg-shot-top\" src=\"http:\/\/i1.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/svg-shot-top.png?resize=545%2C404\" width=\"545\" height=\"404\" \/><\/p>\n<p>We don&#8217;t care so much about the beginning of the SVG file, other than the\u00a0<code>width<\/code>\u00a0and<code>height<\/code>\u00a0variables, but we&#8217;ll get back to that later.<\/p>\n<p>Scroll down some more, and we&#8217;ll get into the\u00a0<a href=\"http:\/\/flowingdata.com\/?attachment_id=3610\">meat of the map<\/a>:<\/p>\n<p>The\u00a0<code>path<\/code>\u00a0tags contain the geographies of each county.<a href=\"http:\/\/flowingdata.com\/2009\/11\/12\/how-to-make-a-us-county-thematic-map-using-free-tools\/svg-shot-middle\/\" rel=\"attachment wp-att-3610\"><img loading=\"lazy\" decoding=\"async\" title=\"svg-shot-middle\" alt=\"svg-shot-middle\" src=\"http:\/\/i1.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/svg-shot-middle.png?resize=545%2C404\" width=\"545\" height=\"404\" \/><\/a><\/p>\n<p>Each\u00a0<code>path<\/code>\u00a0is a county. The long run of numbers are the coordinates for the county&#8217;s boundary lines. We&#8217;re not going to fuss with those numbers.<\/p>\n<p>We only care about the beginning and very end of the\u00a0<code>path<\/code>\u00a0tag. We&#8217;re going to change the<code>style<\/code>\u00a0attribute, namely\u00a0<code>fill<\/code>\u00a0color. We want the darkness of\u00a0<code>fill<\/code>\u00a0to correspond to the unemployment rate in each given county.<\/p>\n<p>We could change each one manually, but there are over 3,000 counties. That would take too long. Instead we&#8217;ll use Beautiful Soup, an XML parsing Python library, to change colors accordingly.<\/p>\n<p>Each\u00a0<code>path<\/code>\u00a0also has an\u00a0<code>id<\/code>, which is actually something called a\u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/FIPS_county_code\">FIPS code<\/a>. FIPS stands for Federal Information Processing Standard. Every county has a unique FIPS code, and it&#8217;s how we are going to associate each path with our unemployment data.<\/p>\n<h3>Step 4. Create Python script<\/h3>\n<p>Open a blank file in the same directory as the SVG map and unemployment data. Save it as<strong>color_map.py<\/strong>.<\/p>\n<h3>Step 5. Import necessary modules<\/h3>\n<p>Our script is going to do a few things. The first is read in our CSV file of unemployment data. So we&#8217;ll import the\u00a0<code>csv<\/code>\u00a0module in Python. We&#8217;re also going to use Beautiful Soup later, so let&#8217;s import that too.<\/p>\n<div id=\"highlighter_362973\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code>import<\/code>\u00a0<code>csv<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>from<\/code>\u00a0<code>BeautifulSoup\u00a0<\/code><code>import<\/code>\u00a0<code>BeautifulSoup<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3>Step 6. Read in unemployment data with Python<\/h3>\n<p>Now let&#8217;s read in the data.<\/p>\n<div id=\"highlighter_943289\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Read in unemployment rates<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>unemployment\u00a0<\/code><code>=<\/code>\u00a0<code>{}<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>3<\/code><\/td>\n<td><code>reader\u00a0<\/code><code>=<\/code>\u00a0<code>csv.reader(<\/code><code>open<\/code><code>(<\/code><code>'unemployment09.csv'<\/code><code>), delimiter<\/code><code>=<\/code><code>\",\"<\/code><code>)<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>4<\/code><\/td>\n<td><code>for<\/code>\u00a0<code>row\u00a0<\/code><code>in<\/code>\u00a0<code>reader:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>5<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>try<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>6<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>full_fips\u00a0<\/code><code>=<\/code>\u00a0<code>row[<\/code><code>1<\/code><code>]\u00a0<\/code><code>+<\/code>\u00a0<code>row[<\/code><code>2<\/code><code>]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>7<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>rate\u00a0<\/code><code>=<\/code>\u00a0<code>float<\/code><code>( row[<\/code><code>8<\/code><code>].strip() )<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>8<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>unemployment[full_fips]\u00a0<\/code><code>=<\/code>\u00a0<code>rate<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>9<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>except<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>10<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>pass<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>We read in the data with\u00a0<code>csv.reader()<\/code>\u00a0and then iterate through each row in the CSV file. The FIPS code is split up in the CSV by state code (second column) and then county code (third column). We put the two together for the full FIPS county code, making a five digit number.<\/p>\n<p>Rate is the ninth column. We convert it to a\u00a0<code>float<\/code>\u00a0since it&#8217;s initially a string when we read it from the CSV.<\/p>\n<p>The\u00a0<code>rate<\/code>\u00a0is then stored in the\u00a0<code>unemployment<\/code>\u00a0dictionary with the\u00a0<code>full_fips<\/code>\u00a0as key.<\/p>\n<p>Cool. The data is in. Now let&#8217;s load the SVG map, which remember, is an XML file.<\/p>\n<h3>Step 7. Load county map<\/h3>\n<p>Loading the map is straightforward. It&#8217;s just one line of code.<\/p>\n<div id=\"highlighter_475004\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Load the SVG map<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>svg\u00a0<\/code><code>=<\/code>\u00a0<code>open<\/code><code>(<\/code><code>'counties.svg'<\/code><code>,\u00a0<\/code><code>'r'<\/code><code>).read()<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The entire string is stored in\u00a0<code>svg<\/code>.<\/p>\n<h3>Step 8. Parse it with Beautiful Soup<\/h3>\n<p>Loading\u00a0<code>svg<\/code>\u00a0into Beautiful Soup is also straightforward.<\/p>\n<div id=\"highlighter_381355\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Load into Beautiful Soup<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>soup\u00a0<\/code><code>=<\/code>\u00a0<code>BeautifulSoup(svg, selfClosingTags<\/code><code>=<\/code><code>[<\/code><code>'defs'<\/code><code>,<\/code><code>'sodipodi:namedview'<\/code><code>])<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3>Step 9. Find all the counties in the SVG<\/h3>\n<p>Beautiful Soup has a nifty\u00a0<code>findAll()<\/code>\u00a0function that we can use to find all the counties in our SVG file.<\/p>\n<div id=\"highlighter_202572\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Find counties<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>paths\u00a0<\/code><code>=<\/code>\u00a0<code>soup.findAll(<\/code><code>'path'<\/code><code>)<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>All paths are stored in the\u00a0<code>paths<\/code>\u00a0array.<\/p>\n<h3>Step 10. Decide what colors to use for map<\/h3>\n<p>There are plenty of color schemes to choose from, but if you don&#8217;t want to think about it, give the\u00a0<a href=\"http:\/\/colorbrewer2.org\/\">ColorBrewer<\/a>\u00a0a whirl. It&#8217;s a tool to help you decide your colors. For this particular map, I chose the PurpleRed scheme with six data classes.<\/p>\n<p>ColorBrewer interface for easy, straightforward way to pick colors<img loading=\"lazy\" decoding=\"async\" title=\"colorbrewer\" alt=\"colorbrewer\" src=\"http:\/\/i1.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/colorbrewer.png?resize=545%2C342\" width=\"545\" height=\"342\" \/><\/p>\n<p>In the bottom, left-hand corner, are our color codes. Select the hexadecimal option (HEX), and then create an array of those hexadecimal colors.<\/p>\n<div id=\"highlighter_632393\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Map colors<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>colors\u00a0<\/code><code>=<\/code>\u00a0<code>[<\/code><code>\"#F1EEF6\"<\/code><code>,\u00a0<\/code><code>\"#D4B9DA\"<\/code><code>,\u00a0<\/code><code>\"#C994C7\"<\/code><code>,\u00a0<\/code><code>\"#DF65B0\"<\/code><code>,\u00a0<\/code><code>\"#DD1C77\"<\/code><code>,<\/code><code>\"#980043\"<\/code><code>]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3>Step 11. Prepare style for paths<\/h3>\n<p>We&#8217;re getting close to the climax. Like I said earlier, we&#8217;re going to change the\u00a0<code>style<\/code>attribute for each path in the SVG. We&#8217;re just interested in fill color, but to make things easier we&#8217;re going to replace the entire\u00a0<code>style<\/code>\u00a0instead of parsing to replace only the color.<\/p>\n<div id=\"highlighter_783749\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># County style<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>'font<\/code><code>-<\/code><code>size:<\/code><code>12px<\/code><code>;fill<\/code><code>-<\/code><code>rule:nonzero;stroke:<\/code><code>#FFFFFF;stroke-opacity:1;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>3<\/code><\/td>\n<td><code>stroke<\/code><code>-<\/code><code>width:<\/code><code>0.1<\/code><code>;stroke<\/code><code>-<\/code><code>miterlimit:<\/code><code>4<\/code><code>;stroke<\/code><code>-<\/code><code>dasharray:none;stroke<\/code><code>-<\/code><code>linecap:butt;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>4<\/code><\/td>\n<td><code>marker<\/code><code>-<\/code><code>start:none;stroke<\/code><code>-<\/code><code>linejoin:bevel;fill:'<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Everything is the same as the previous style except we moved\u00a0<code>fill<\/code>\u00a0to the end and left the value blank. We&#8217;re going to fill that in just a second. We also changed\u00a0<code>stroke<\/code>\u00a0to\u00a0<code>#FFFFFF<\/code>\u00a0to make county borders white. We didn&#8217;t have to leave that value blank, because we want all borders to be white while\u00a0<code>fill<\/code>\u00a0depends on unemployment rate.<\/p>\n<h3>Step 12. Change color of counties<\/h3>\n<p>We&#8217;re ready to change colors now! Loop through all the paths, find the unemployment rate from the\u00a0<code>unemployment<\/code>\u00a0dictionary, and then select color class accordingly. Here&#8217;s the code:<\/p>\n<div id=\"highlighter_749690\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Color the counties based on unemployment rate<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>for<\/code>\u00a0<code>p\u00a0<\/code><code>in<\/code>\u00a0<code>paths:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>3<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>4<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>if<\/code>\u00a0<code>p[<\/code><code>'id'<\/code><code>]\u00a0<\/code><code>not<\/code>\u00a0<code>in<\/code>\u00a0<code>[<\/code><code>\"State_Lines\"<\/code><code>,\u00a0<\/code><code>\"separator\"<\/code><code>]:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>5<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code># pass<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>6<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>try<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>7<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>rate\u00a0<\/code><code>=<\/code>\u00a0<code>unemployment[p[<\/code><code>'id'<\/code><code>]]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>8<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>except<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>9<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>continue<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>10<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>11<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>if<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>10<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>12<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>5<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>13<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>8<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>14<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>4<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>15<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>6<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>16<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>3<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>17<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>4<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>18<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>2<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>19<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>2<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>20<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>1<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>21<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>else<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>22<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>23<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>24<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color\u00a0<\/code><code>=<\/code>\u00a0<code>colors[color_class]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>25<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>p[<\/code><code>'style'<\/code><code>]\u00a0<\/code><code>=<\/code>\u00a0<code>path_style\u00a0<\/code><code>+<\/code>\u00a0<code>color<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Notice the\u00a0<code>if<\/code>\u00a0statement. I don&#8217;t want to change the style of state lines or the line that separates Hawaii and Alaska from the rest of the states.<\/p>\n<p>I also hard-coded the conditions to decide the color class because I knew beforehand what the distribution is like. If however, you didn&#8217;t know the distribution, you could use something like this:\u00a0<code>float(len(colors)-1) * float(rate - min_value) \/ float(max_value - min_value)<\/code>.<\/p>\n<h3>Step 13. Output modified map<\/h3>\n<p>Almost done. We just need to output the newly colored SVG map.<\/p>\n<div id=\"highlighter_404121\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code># Output map<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><code>print<\/code>\u00a0<code>soup.prettify()<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Save your Python script. For the sake of completeness, here&#8217;s what your Python script should now look like:<\/p>\n<div id=\"highlighter_772313\">\n<div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>1<\/code><\/td>\n<td><code>### color_map.py<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>2<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>3<\/code><\/td>\n<td><code>import<\/code>\u00a0<code>csv<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>4<\/code><\/td>\n<td><code>from<\/code>\u00a0<code>BeautifulSoup\u00a0<\/code><code>import<\/code>\u00a0<code>BeautifulSoup<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>5<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>6<\/code><\/td>\n<td><code># Read in unemployment rates<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>7<\/code><\/td>\n<td><code>unemployment\u00a0<\/code><code>=<\/code>\u00a0<code>{}<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>8<\/code><\/td>\n<td><code>min_value\u00a0<\/code><code>=<\/code>\u00a0<code>100<\/code><code>; max_value\u00a0<\/code><code>=<\/code>\u00a0<code>0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>9<\/code><\/td>\n<td><code>reader\u00a0<\/code><code>=<\/code>\u00a0<code>csv.reader(<\/code><code>open<\/code><code>(<\/code><code>'unemployment09.csv'<\/code><code>), delimiter<\/code><code>=<\/code><code>\",\"<\/code><code>)<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>10<\/code><\/td>\n<td><code>for<\/code>\u00a0<code>row\u00a0<\/code><code>in<\/code>\u00a0<code>reader:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>11<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>try<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>12<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>full_fips\u00a0<\/code><code>=<\/code>\u00a0<code>row[<\/code><code>1<\/code><code>]\u00a0<\/code><code>+<\/code>\u00a0<code>row[<\/code><code>2<\/code><code>]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>13<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>rate\u00a0<\/code><code>=<\/code>\u00a0<code>float<\/code><code>( row[<\/code><code>8<\/code><code>].strip() )<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>14<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>unemployment[full_fips]\u00a0<\/code><code>=<\/code>\u00a0<code>rate<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>15<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>except<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>16<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>pass<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>17<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>18<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>19<\/code><\/td>\n<td><code># Load the SVG map<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>20<\/code><\/td>\n<td><code>svg\u00a0<\/code><code>=<\/code>\u00a0<code>open<\/code><code>(<\/code><code>'counties.svg'<\/code><code>,\u00a0<\/code><code>'r'<\/code><code>).read()<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>21<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>22<\/code><\/td>\n<td><code># Load into Beautiful Soup<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>23<\/code><\/td>\n<td><code>soup\u00a0<\/code><code>=<\/code>\u00a0<code>BeautifulSoup(svg, selfClosingTags<\/code><code>=<\/code><code>[<\/code><code>'defs'<\/code><code>,<\/code><code>'sodipodi:namedview'<\/code><code>])<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>24<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>25<\/code><\/td>\n<td><code># Find counties<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>26<\/code><\/td>\n<td><code>paths\u00a0<\/code><code>=<\/code>\u00a0<code>soup.findAll(<\/code><code>'path'<\/code><code>)<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>27<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>28<\/code><\/td>\n<td><code># Map colors<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>29<\/code><\/td>\n<td><code>colors\u00a0<\/code><code>=<\/code>\u00a0<code>[<\/code><code>\"#F1EEF6\"<\/code><code>,\u00a0<\/code><code>\"#D4B9DA\"<\/code><code>,\u00a0<\/code><code>\"#C994C7\"<\/code><code>,\u00a0<\/code><code>\"#DF65B0\"<\/code><code>,\u00a0<\/code><code>\"#DD1C77\"<\/code><code>,<\/code><code>\"#980043\"<\/code><code>]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>30<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>31<\/code><\/td>\n<td><code># County style<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>32<\/code><\/td>\n<td><code>path_style\u00a0<\/code><code>=<\/code>\u00a0<code>'font<\/code><code>-<\/code><code>size:<\/code><code>12px<\/code><code>;fill<\/code><code>-<\/code><code>rule:nonzero;stroke:<\/code><code>#FFFFFF;stroke-opacity:1;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>33<\/code><\/td>\n<td><code>stroke<\/code><code>-<\/code><code>width:<\/code><code>0.1<\/code><code>;stroke<\/code><code>-<\/code><code>miterlimit:<\/code><code>4<\/code><code>;stroke<\/code><code>-<\/code><code>dasharray:none;stroke<\/code><code>-<\/code><code>linecap:butt;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>34<\/code><\/td>\n<td><code>marker<\/code><code>-<\/code><code>start:none;stroke<\/code><code>-<\/code><code>linejoin:bevel;fill:'<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>35<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>36<\/code><\/td>\n<td><code># Color the counties based on unemployment rate<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>37<\/code><\/td>\n<td><code>for<\/code>\u00a0<code>p\u00a0<\/code><code>in<\/code>\u00a0<code>paths:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>38<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>39<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0<\/code><code>if<\/code>\u00a0<code>p[<\/code><code>'id'<\/code><code>]\u00a0<\/code><code>not<\/code>\u00a0<code>in<\/code>\u00a0<code>[<\/code><code>\"State_Lines\"<\/code><code>,\u00a0<\/code><code>\"separator\"<\/code><code>]:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>40<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>try<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>41<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>rate\u00a0<\/code><code>=<\/code>\u00a0<code>unemployment[p[<\/code><code>'id'<\/code><code>]]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>42<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>except<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>43<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>continue<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>44<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>45<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>46<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>if<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>10<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>47<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>5<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>48<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>8<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>49<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>4<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>50<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>6<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>51<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>3<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>52<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>4<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>53<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>2<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>54<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>elif<\/code>\u00a0<code>rate &gt;\u00a0<\/code><code>2<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>55<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>1<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>56<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>else<\/code><code>:<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>57<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color_class\u00a0<\/code><code>=<\/code>\u00a0<code>0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>58<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>59<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>60<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>color\u00a0<\/code><code>=<\/code>\u00a0<code>colors[color_class]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>61<\/code><\/td>\n<td><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/code><code>p[<\/code><code>'style'<\/code><code>]\u00a0<\/code><code>=<\/code>\u00a0<code>path_style\u00a0<\/code><code>+<\/code>\u00a0<code>color<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>62<\/code><\/td>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td><code>63<\/code><\/td>\n<td><code>print<\/code>\u00a0<code>soup.prettify()<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3>Step 14. Run script and save new map<\/h3>\n<p>Now all we have to do is run our script and save the output.<\/p>\n<p>Running script in OS X Terminal<a href=\"http:\/\/flowingdata.com\/2009\/11\/12\/how-to-make-a-us-county-thematic-map-using-free-tools\/terminal-out\/\" rel=\"attachment wp-att-3662\"><img loading=\"lazy\" decoding=\"async\" title=\"terminal-out\" alt=\"terminal-out\" src=\"http:\/\/i2.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/terminal-out.png?resize=545%2C436\" width=\"545\" height=\"436\" \/><\/a><\/p>\n<p>We&#8217;re done! Open your SVG in FIrefox or Safari, and you should see a nicely colored map similar to the one below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"choropleth06\" src=\"http:\/\/i1.wp.com\/flowingdata.com\/wp-content\/uploads\/2009\/11\/choropleth061.png?resize=625%2C396\" width=\"625\" height=\"396\" \/><\/p>\n<p>Oh wait, there&#8217;s one teeny little thing. The state borders are still dark grey. We can make those white by editing the the SVG file manually.<\/p>\n<p>We open our new SVG in a text editor, and change the stroke to\u00a0<code>#FFFFFF<\/code>\u00a0from\u00a0<code>#221e1f<\/code>around line 15780. Do something similar on line 15785 for the separator. Okay. Now we&#8217;re done.<\/p>\n<h3>Where to Go From Here<\/h3>\n<p>While this tutorial was focused on unemployment data, I tried to keep it general enough so that you could apply it to other datasets. All you need are data with FIPS codes, and it should be fairly straightforward to hack the above script.<\/p>\n<p>You can also load the SVG into Adobe Illustrator or your favorite open source vector art software and edit the map from there, which is what I did for the\u00a0<a href=\"http:\/\/projects.flowingdata.com\/america\/unemployment\/\">final graphic<\/a>.<\/p>\n<p>So go ahead. Give it a try. Have fun.<\/p>\n<p>For more examples, guidance, and all-around data goodness like this,\u00a0<a href=\"http:\/\/flowingdata.com\/book\/\">order Visualize This<\/a>, the FlowingData book on visualization, design, and statistics.<\/p>\n<div><\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div id=\"end\"><\/div>\n<div>\n<p>Become a FlowingData member, and get instant access to tutorials and resources.<\/p>\n<div><a href=\"http:\/\/flowingdata.com\/membership\/\">Join Now<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>By\u00a0NATHAN YAU There are about a million ways to make a choropleth map. The problem is that a lot of solutions require expensive software or&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-424","post","type-post","status-publish","format-standard","hentry","category-arcgis"],"_links":{"self":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/424","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/comments?post=424"}],"version-history":[{"count":0,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/424\/revisions"}],"wp:attachment":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/media?parent=424"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/categories?post=424"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/tags?post=424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}