{
 "metadata": {
  "name": "",
  "signature": "sha256:a21899f81930013ea201161ec6b01b069282c7f5b36dd0ac860b43ccaf80eb49"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Mapping using Pysal and Folium: Example"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import pysal as ps\n",
      "import geojson as gj\n",
      "import folium_mapping as fm"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "First, we need to convert the data into a JSON format. JSON, short for \"Javascript Serialized Object Notation,\" is a simple and effective way to represent objects in a digital environment. For geographic information, the [GeoJSON](https://geojson.org) standard defines how to represent geographic information in JSON format. Python programmers may be more comfortable thinking of JSON data as something akin to a standard Python dictionary. "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "filepath = ps.examples.get_path('south.shp')[:-4]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "shp = ps.open(filepath + '.shp')\n",
      "dbf = ps.open(filepath + '.dbf')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js = fm.build_features(shp, dbf)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 4
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Just to show, this constructs a dictionary with the following keys:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js.keys()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 5,
       "text": [
        "['type', 'bbox', 'features']"
       ]
      }
     ],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js.type"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 6,
       "text": [
        "'FeatureCollection'"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js.bbox"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 7,
       "text": [
        "[-106.6495132446289, 24.95596694946289, -75.0459976196289, 40.63713836669922]"
       ]
      }
     ],
     "prompt_number": 7
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js.features[0]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 8,
       "text": [
        "{\"bbox\": [-80.6688232421875, 40.39815902709961, -80.52220916748047, 40.63713836669922], \"geometry\": {\"coordinates\": [[[-80.6280517578125, 40.39815902709961], [-80.60203552246094, 40.480472564697266], [-80.62545776367188, 40.504398345947266], [-80.6336441040039, 40.53913879394531], [-80.6688232421875, 40.568214416503906], [-80.66793060302734, 40.58207321166992], [-80.63754272460938, 40.61391830444336], [-80.61175537109375, 40.619998931884766], [-80.57462310791016, 40.615909576416016], [-80.52220916748047, 40.63713836669922], [-80.52456665039062, 40.47871780395508], [-80.52377319335938, 40.4029655456543], [-80.6280517578125, 40.39815902709961]]], \"type\": \"Polygon\"}, \"id\": null, \"properties\": {\"BLK60\": 3.839454752, \"BLK70\": 3.2554278095, \"BLK80\": 2.5607402642, \"BLK90\": 2.5572616581, \"CNTY_FIPS\": \"029\", \"COFIPS\": 29, \"DNL60\": 6.1681225056, \"DNL70\": 6.1714993547, \"DNL80\": 6.1714631077, \"DNL90\": 6.0508978146, \"DV60\": 2.2779893943, \"DV70\": 2.5591397849, \"DV80\": 5.0619350519, \"DV90\": 7.2636377003, \"FH60\": 9.9812973718, \"FH70\": 7.8, \"FH80\": 9.7857968181, \"FH90\": 12.604551644, \"FIPS\": \"54029\", \"FIPSNO\": 54029, \"FP59\": 9.6, \"FP69\": 5.9, \"FP79\": 6.5327526442, \"FP89\": 10.17311807, \"GI59\": 0.2236450331, \"GI69\": 0.2953773833, \"GI79\": 0.3322512119, \"GI89\": 0.3639335641, \"HC60\": 0.6666666667, \"HC70\": 1.6666666667, \"HC80\": 2.6666666667, \"HC90\": 0.3333333333, \"HR60\": 1.6828642349, \"HR70\": 4.1929776011, \"HR80\": 6.5977204876, \"HR90\": 0.9460827444, \"MA60\": 28.9, \"MA70\": 30.0, \"MA80\": 31.4, \"MA90\": 37.7, \"MFIL59\": 8.8410143105, \"MFIL69\": 9.2471543451, \"MFIL79\": 10.073356901, \"MFIL89\": 10.327970666, \"NAME\": \"Hancock\", \"PO60\": 39615, \"PO70\": 39749, \"PO80\": 40418, \"PO90\": 35233, \"POL60\": 10.586963113, \"POL70\": 10.590339963, \"POL80\": 10.607030509, \"POL90\": 10.469738422, \"PS60\": 1.218684208, \"PS70\": 1.1368342185, \"PS80\": 1.0385705291, \"PS90\": 0.8964534429, \"RD60\": -1.394676863, \"RD70\": -1.307438562, \"RD80\": -1.159302086, \"RD90\": -0.399028376, \"SOUTH\": 1, \"STATE_FIPS\": \"54\", \"STATE_NAME\": \"West Virginia\", \"STFIPS\": 54, \"UE60\": 3.1, \"UE70\": 2.7, \"UE80\": 7.0763827919, \"UE90\": 6.8578070515}, \"type\": \"Feature\"}"
       ]
      }
     ],
     "prompt_number": 8
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Then, we write the json to a file. "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "with open('./example.json', 'w') as out:\n",
      "    gj.dump(js, out)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 9
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Mapping"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's look at the columns that we're going to map."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "js.features[0].properties.keys()[0:5]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 11,
       "text": [
        "['HR90', 'PS90', 'FH80', 'HC60', 'FP79']"
       ]
      }
     ],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We can map these attributes by calling them as commands to the choropleth mapping function. \n",
      "\n",
      "Here's the simplest mapping command:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR90')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([4.1795187812600005, 6.904210850319998, 9.783181576819999, 14.2778818492])\n",
        "              .range(['#FFFFCC', '#D9F0A3', '#ADDD8E', '#78C679', '#41AB5D']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map data (c) <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a> contributors'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 15])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([4.1795187812600005, 6.904210850319998, 9.783181576819999, 14.2778818492]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR90');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 12,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fddcc150>"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This produces a map using default classifications and color schemes and saves it to an html file. We set the function to have sane defaults. However, if the user wants to have more control, we have many options available. "
     ]
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "There are arguments to change classification scheme:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR90', classification = 'Quantiles')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([4.1795187812600005, 6.904210850319998, 9.783181576819999, 14.2778818492])\n",
        "              .range(['#FFFFCC', '#D9F0A3', '#ADDD8E', '#78C679', '#41AB5D']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map data (c) <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a> contributors'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 15])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([4.1795187812600005, 6.904210850319998, 9.783181576819999, 14.2778818492]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR90');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 13,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fddcc9d0>"
       ]
      }
     ],
     "prompt_number": 13
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Most `PySAL` classifiers are supprorted. "
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Base Map Type"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR90', classification = 'Jenks Caspall', tiles='Stamen Toner', save=True) "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([2.3886301206, 6.7263065851, 11.080639353, 17.516035134])\n",
        "              .range(['#FFFFCC', '#D9F0A3', '#ADDD8E', '#78C679', '#41AB5D']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map tiles by <a href=&quot;http://stamen.com&quot;>Stamen Design</a>, under <a href=&quot;http://creativecommons.org/licenses/by/3.0&quot;>CC BY 3.0</a>. Data by <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a>, under <a href=&quot;http://creativecommons.org/licenses/by-sa/3.0&quot;>CC BY SA</a>.'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 19])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([2.3886301206, 6.7263065851, 11.080639353, 17.516035134]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR90');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 15,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fddcc090>"
       ]
      }
     ],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We support the entire range of builtin basemap types in Folium, but custom tilesets from MapBox are not supported yet. "
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Color Scheme"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR80', classification = 'Jenks Caspall', tiles='Stamen Toner', fill_color = 'PuBuGn', save=True) "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([5.0172467858, 8.749365671, 12.657426745, 17.721070353])\n",
        "              .range(['#F6EFF7', '#D0D1E6', '#A6BDDB', '#67A9CF', '#3690C0']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map tiles by <a href=&quot;http://stamen.com&quot;>Stamen Design</a>, under <a href=&quot;http://creativecommons.org/licenses/by/3.0&quot;>CC BY 3.0</a>. Data by <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a>, under <a href=&quot;http://creativecommons.org/licenses/by-sa/3.0&quot;>CC BY SA</a>.'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 19])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([5.0172467858, 8.749365671, 12.657426745, 17.721070353]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR80');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 16,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fcb72590>"
       ]
      }
     ],
     "prompt_number": 16
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "All color schemes are [Color Brewer](https://colorbrewer2.org) and simply pass through to `Folium` on execution. "
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Class numbers"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR80', classification = 'Equal Interval', classes=6, tiles='Stamen Toner', fill_color='PuBuGn',save=True) "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([7.057234169166667, 14.114468338333333, 21.1717025075, 28.228936676666667, 35.28617084583333])\n",
        "              .range(['#F6EFF7', '#D0D1E6', '#A6BDDB', '#67A9CF', '#3690C0', '#02818A']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map tiles by <a href=&quot;http://stamen.com&quot;>Stamen Design</a>, under <a href=&quot;http://creativecommons.org/licenses/by/3.0&quot;>CC BY 3.0</a>. Data by <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a>, under <a href=&quot;http://creativecommons.org/licenses/by-sa/3.0&quot;>CC BY SA</a>.'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 38])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([7.057234169166667, 14.114468338333333, 21.1717025075, 28.228936676666667, 35.28617084583333]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR80');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 18,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fcb729d0>"
       ]
      }
     ],
     "prompt_number": 18
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Folium supports up to 6 classes."
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Standardization"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fm.choropleth_map('./example.json', 'FIPS', 'HR90', classification = 'Quantiles', std='HR80' , tiles='Stamen Toner', fill_color='PuBuGn',save=True) "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, './example.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([0.5185943291795233, 0.7967324987903716, 1.0780871918834456, 1.7476117844514245])\n",
        "              .range(['#F6EFF7', '#D0D1E6', '#A6BDDB', '#67A9CF', '#3690C0']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map tiles by <a href=&quot;http://stamen.com&quot;>Stamen Design</a>, under <a href=&quot;http://creativecommons.org/licenses/by/3.0&quot;>CC BY 3.0</a>. Data by <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a>, under <a href=&quot;http://creativecommons.org/licenses/by-sa/3.0&quot;>CC BY SA</a>.'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 1])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([0.5185943291795233, 0.7967324987903716, 1.0780871918834456, 1.7476117844514245]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR90');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 19,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fcb72a10>"
       ]
      }
     ],
     "prompt_number": 19
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The goal of the `std` argument was to implement a very flexible transformation argument that could take functions, fields, and static items. As of now, it only supports float/int scaling and division by another field, which would support the mapping of spatial rates or population rates."
     ]
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Conclusion"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Overall, the function neatly encapsulates three components:\n",
      "\n",
      "- plumbing large lists of arguments together to simplify mapping from JSON files\n",
      "- searching for sane defaults (bounding box & zoom level)\n",
      "- implementing classification and standardization useful for choropleth mapping"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Due to some pretty strong limitations in `Folium` itself, its usefulness for rich, dynamic, and interactive visualizations built from small, atomic functions is probably limited. It would need to be extended quite significantly (or linked with even more packages with more fickle APIs) to usefully generate mixed-mode scientific visualizations. With `Folium`'s natural linkages to `Pandas`, mapping derived quantites is also possible.\n",
      "\n",
      "But, it's really simple to map quickly from PySAL:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "with open('example2.json', 'w') as out:\n",
      "    gj.dump(fm.build_features(ps.open(filepath + '.shp'), ps.open(filepath + '.dbf')), out)\n",
      "fm.choropleth_map('example2.json', 'FIPS', 'HR70')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<iframe srcdoc=\"<!DOCTYPE html>\n",
        "<head>\n",
        "   <meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot; />\n",
        "   <link rel=&quot;stylesheet&quot; href=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.css&quot; />\n",
        "   <script src=&quot;http://cdn.leafletjs.com/leaflet-0.7/leaflet.js&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/d3.v3.min.js&quot; charset=&quot;utf-8&quot;></script>\n",
        "   <script src=&quot;http://d3js.org/queue.v1.min.js&quot;></script>\n",
        "\n",
        "   \n",
        "   \n",
        "   \n",
        "   \n",
        "\n",
        "   <style>\n",
        "\n",
        "      html, body {\n",
        "        width: 100%;\n",
        "        height: 100%;\n",
        "        margin: 0;\n",
        "        padding: 0;\n",
        "      }\n",
        "\n",
        "      .legend {\n",
        "          padding: 0px 0px;\n",
        "          font: 10px sans-serif;\n",
        "          background: white;\n",
        "          background: rgba(255,255,255,0.8);\n",
        "          box-shadow: 0 0 15px rgba(0,0,0,0.2);\n",
        "          border-radius: 5px;\n",
        "      }\n",
        "\n",
        "      .key path {\n",
        "        display: none;\n",
        "      }\n",
        "\n",
        "   </style>\n",
        "</head>\n",
        "\n",
        "<body>\n",
        "\n",
        "   <div id=&quot;map&quot; style=&quot;width: 960px; height: 500px&quot;></div>\n",
        "\n",
        "   <script>\n",
        "\n",
        "      queue()\n",
        "          .defer(d3.json, 'data.json')\n",
        "          .defer(d3.json, 'example2.json')\n",
        "          .await(makeMap)\n",
        "\n",
        "      function makeMap(error, data_1,gjson_1) {\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          function matchKey(datapoint, key_variable){\n",
        "              if (typeof key_variable[0][datapoint] === 'undefined') {\n",
        "                  return null;\n",
        "              }\n",
        "              else {\n",
        "                  return parseFloat(key_variable[0][datapoint]);\n",
        "              };\n",
        "          };\n",
        "\n",
        "          \n",
        "          var color = d3.scale.threshold()\n",
        "              .domain([4.13585524408, 7.479368277879999, 10.925812736200001, 15.4596870396])\n",
        "              .range(['#FFFFCC', '#D9F0A3', '#ADDD8E', '#78C679', '#41AB5D']);\n",
        "          \n",
        "\n",
        "          var map = L.map('map').setView([32.7965526581, -90.8477554321], 5);\n",
        "\n",
        "          L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n",
        "              maxZoom: 18,\n",
        "              attribution: 'Map data (c) <a href=&quot;http://openstreetmap.org&quot;>OpenStreetMap</a> contributors'\n",
        "          }).addTo(map);\n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "\n",
        "          \n",
        "          function style_1(feature) {\n",
        "    return {\n",
        "        fillColor: color(matchKey(feature.properties.FIPS, data_1)),\n",
        "        weight: 1,\n",
        "        opacity: 0.2,\n",
        "        color: 'black',\n",
        "        fillOpacity: 0.5\n",
        "    };\n",
        "}\n",
        "          \n",
        "\n",
        "          \n",
        "          gJson_layer_1 = L.geoJson(gjson_1, {style: style_1}).addTo(map)\n",
        "          \n",
        "\n",
        "          \n",
        "              var legend = L.control({position: 'topright'});\n",
        "\n",
        "    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};\n",
        "\n",
        "    legend.addTo(map);\n",
        "\n",
        "    var x = d3.scale.linear()\n",
        "    .domain([0, 17])\n",
        "    .range([0, 400]);\n",
        "\n",
        "    var xAxis = d3.svg.axis()\n",
        "        .scale(x)\n",
        "        .orient(&quot;top&quot;)\n",
        "        .tickSize(1)\n",
        "        .tickValues([4.13585524408, 7.479368277879999, 10.925812736200001, 15.4596870396]);\n",
        "\n",
        "    var svg = d3.select(&quot;.legend.leaflet-control&quot;).append(&quot;svg&quot;)\n",
        "        .attr(&quot;id&quot;, 'legend')\n",
        "        .attr(&quot;width&quot;, 450)\n",
        "        .attr(&quot;height&quot;, 40);\n",
        "\n",
        "    var g = svg.append(&quot;g&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;key&quot;)\n",
        "        .attr(&quot;transform&quot;, &quot;translate(25,16)&quot;);\n",
        "\n",
        "    g.selectAll(&quot;rect&quot;)\n",
        "        .data(color.range().map(function(d, i) {\n",
        "          return {\n",
        "            x0: i ? x(color.domain()[i - 1]) : x.range()[0],\n",
        "            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],\n",
        "            z: d\n",
        "          };\n",
        "        }))\n",
        "      .enter().append(&quot;rect&quot;)\n",
        "        .attr(&quot;height&quot;, 10)\n",
        "        .attr(&quot;x&quot;, function(d) { return d.x0; })\n",
        "        .attr(&quot;width&quot;, function(d) { return d.x1 - d.x0; })\n",
        "        .style(&quot;fill&quot;, function(d) { return d.z; });\n",
        "\n",
        "    g.call(xAxis).append(&quot;text&quot;)\n",
        "        .attr(&quot;class&quot;, &quot;caption&quot;)\n",
        "        .attr(&quot;y&quot;, 21)\n",
        "        .text('HR70');\n",
        "          \n",
        "\n",
        "      };\n",
        "\n",
        "   </script>\n",
        "</body>\" style=\"width: 100%; height: 510px; border: none\"></iframe>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 22,
       "text": [
        "<IPython.core.display.HTML at 0x7f53fd177810>"
       ]
      }
     ],
     "prompt_number": 22
    }
   ],
   "metadata": {}
  }
 ]
}