block by ThomasG77 ba74aeceb82ba00ca603

ba74aeceb82ba00ca603

Full Screen

A Leaflet.js map created with Folium and a custom D3 threshold scale, with data bound between the Pandas DataFrame and the TopoJSON. See the Gist for the python code to generate the dataframe. The map was generated with the following Python code:

map_3 = folium.Map(location=[40, -99], zoom_start=4)
map_3.geo_json(geo_path=county_geo, data_out='data3.json', data=df,
               columns=['GEO_ID', 'Median_Household_Income_2011'],
               key_on='feature.id',
               fill_color='PuRd', line_opacity=0.3,
               legend_name='Median Household Income 2011 ($)',
               topojson='objects.us_counties_20m')
map_3.create_map(path='map_3.html')

index.html

<!DOCTYPE html>
<head>
   <link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
   <script src="//cdn.leafletjs.com/leaflet-0.5/leaflet.js"></script>
   <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
   <script src="//d3js.org/queue.v1.min.js"></script>

   <script src="//d3js.org/topojson.v1.min.js"></script>


<style>

.legend {
    padding: 0px 0px;
    font: 10px sans-serif;
    background: white;
    background: rgba(255,255,255,0.8);
    box-shadow: 0 0 15px rgba(0,0,0,0.2);
    border-radius: 5px;
}

.key path {
  display: none;
}

</style>
</head>
<body>

        <div id="map" style="width: 960px; height: 500px"></div>

<script>

queue()
    .defer(d3.json, 'data3.json')
    .defer(d3.json, 'us_counties_20m_topo.json')
    .await(makeMap)

function makeMap(error, data_1,tjson_1) {


    topo_1 = topojson.feature(tjson_1, tjson_1.objects.us_counties_20m);




    function matchKey(datapoint, key_variable){
        return(parseFloat(key_variable[0][datapoint]));
    };


    var color = d3.scale.threshold()
              .domain([20000.0, 40000.0, 50000.0, 50000.0, 60000.0])
              .range(['#F1EEF6', '#D4B9DA', '#C994C7', '#DF65B0', '#E7298A', '#CE1256']);


    var map = L.map('map').setView([40, -99], 4);

    L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 18,
        attribution: 'Map data (c) <a href="//openstreetmap.org">OpenStreetMap</a> contributors'
    }).addTo(map);








    function style_1(feature) {
    return {
        fillColor: color(matchKey(feature.id, data_1)),
        weight: 1,
        opacity: 0.3,
        color: 'black',
        fillOpacity: 0.6
    };
}



    gJson_layer_1 = L.geoJson(topo_1, {style: style_1}).addTo(map)



        var legend = L.control({position: 'topright'});

    legend.onAdd = function (map) {var div = L.DomUtil.create('div', 'legend'); return div};

    legend.addTo(map);

    var x = d3.scale.linear()
    .domain([0, 66000])
    .range([0, 400]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("top")
        .tickSize(1)
        .tickValues(color.domain())

    var svg = d3.select(".legend.leaflet-control").append("svg")
        .attr("id", 'legend')
        .attr("width", 450)
        .attr("height", 40);

    var g = svg.append("g")
        .attr("class", "key")
        .attr("transform", "translate(25,16)");

    g.selectAll("rect")
        .data(color.range().map(function(d, i) {
          return {
            x0: i ? x(color.domain()[i - 1]) : x.range()[0],
            x1: i < color.domain().length ? x(color.domain()[i]) : x.range()[1],
            z: d
          };
        }))
      .enter().append("rect")
        .attr("height", 10)
        .attr("x", function(d) { return d.x0; })
        .attr("width", function(d) { return d.x1 - d.x0; })
        .style("fill", function(d) { return d.z; });

    g.call(xAxis).append("text")
        .attr("class", "caption")
        .attr("y", 21)
        .text('Median Household Income 2011 ($)');


};

</script>

</body>

choro.py

import folium
import pandas as pd

county_data = r'us_county_data.csv'
county_geo = r'us_counties_20m_topo.json'

#Read into Dataframe, cast to string for consistency
df = pd.read_csv(county_data, na_values=[' '])
df['FIPS_Code'] = df['FIPS_Code'].astype(str)


def set_id(fips):
    '''Modify FIPS code to match GeoJSON property'''
    if fips == '0':
        return None
    elif len(fips) <= 4:
        return ''.join(['0500000US0', fips])
    else:
        return ''.join(['0500000US', fips])

#Apply set_id, drop NaN
df['GEO_ID'] = df['FIPS_Code'].apply(set_id)
df = df.dropna()

map_3 = folium.Map(location=[40, -99], zoom_start=4)
map_3.geo_json(geo_path=county_geo, data_out='data3.json', data=df,
               columns=['GEO_ID', 'Median_Household_Income_2011'],
               key_on='feature.id',
               fill_color='PuRd', line_opacity=0.3,
               legend_name='Median Household Income 2011 ($)',
               topojson='objects.us_counties_20m')
map_3.create_map(path='map_3.html')