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')
xxxxxxxxxx
<head>
<link rel="stylesheet" href="https://cdn.leafletjs.com/leaflet-0.5/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.5/leaflet.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<script src="https://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('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data (c) <a href="https://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>
Modified http://cdn.leafletjs.com/leaflet-0.5/leaflet.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/queue.v1.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://cdn.leafletjs.com/leaflet-0.5/leaflet.js
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js
https://d3js.org/topojson.v1.min.js