Forked from rutgerhofste/gist:a0b0c89aff9d271691b62c433fbd467c
Last active
July 5, 2018 13:06
-
-
Save ryanbaumann/ce718be93056f7810072950975777dda to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from mapboxgl.utils import create_color_stops\n", | |
"from mapboxgl.viz import *\n", | |
"import geojson" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data_url = 'pop.geojson'\n", | |
"token = os.getenv('MAPBOX_ACCESS_TOKEN')\n", | |
"measure = 'pop_est'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<iframe id=\"map\", srcdoc=\"<!DOCTYPE html>\n", | |
"<html>\n", | |
"<head>\n", | |
"<title>mapboxgl-jupyter viz</title>\n", | |
"<meta charset='UTF-8' />\n", | |
"<meta name='viewport'\n", | |
" content='initial-scale=1,maximum-scale=1,user-scalable=no' />\n", | |
"<script type='text/javascript'\n", | |
" src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.42.2/mapbox-gl.js'></script>\n", | |
"<link type='text/css'\n", | |
" href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.42.2/mapbox-gl.css' rel='stylesheet' />\n", | |
"<style type='text/css'>\n", | |
" body { margin:0; padding:0; }\n", | |
" .map { position:absolute; top:0; bottom:0; width:100%; }\n", | |
" .legend {\n", | |
" background-color: white;\n", | |
" color: black;\n", | |
" border-radius: 3px;\n", | |
" bottom: 50px;\n", | |
" width: 100px;\n", | |
" box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);\n", | |
" font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;\n", | |
" padding: 12px;\n", | |
" position: absolute;\n", | |
" right: 10px;\n", | |
" z-index: 1;\n", | |
" }\n", | |
" .legend h4 { margin: 0 0 10px; }\n", | |
" .legend-title {\n", | |
" margin: 6px;\n", | |
" padding: 6px;\n", | |
" font-weight: bold !important;\n", | |
" font-size: 14px;\n", | |
" font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;\n", | |
" }\n", | |
" .legend div span {\n", | |
" border-radius: 50%;\n", | |
" display: inline-block;\n", | |
" height: 10px;\n", | |
" margin-right: 5px;\n", | |
" width: 10px;\n", | |
" }\n", | |
"</style>\n", | |
"\n", | |
" <style type='text/css'>\n", | |
" .legend div span { border-radius: 20%; }\n", | |
" </style>\n", | |
"\n", | |
"</head>\n", | |
"<body>\n", | |
"\n", | |
"<div id='map' class='map'></div>\n", | |
"<div id='legend' class='legend'></div>\n", | |
"\n", | |
"<script type='text/javascript'>\n", | |
"\n", | |
"function calcCircleColorLegend(myColorStops, title) {\n", | |
" //Calculate a legend element on a Mapbox GL Style Spec property function stops array\n", | |
" var mytitle = document.createElement('div');\n", | |
" mytitle.textContent = title;\n", | |
" mytitle.className = 'legend-title'\n", | |
" var legend = document.getElementById('legend');\n", | |
" legend.appendChild(mytitle);\n", | |
"\n", | |
" for (p = 0; p < myColorStops.length; p++) {\n", | |
" if (!!document.getElementById('legend-points-value-' + p)) {\n", | |
" //update the legend if it already exists\n", | |
" document.getElementById('legend-points-value-' + p).textContent = myColorStops[p][0];\n", | |
" document.getElementById('legend-points-id-' + p).style.backgroundColor = myColorStops[p][1];\n", | |
" } else {\n", | |
" //create the legend if it doesn't yet exist\n", | |
" var item = document.createElement('div');\n", | |
" var key = document.createElement('span');\n", | |
" key.className = 'legend-key';\n", | |
" var value = document.createElement('span');\n", | |
"\n", | |
" key.id = 'legend-points-id-' + p;\n", | |
" key.style.backgroundColor = myColorStops[p][1];\n", | |
" value.id = 'legend-points-value-' + p;\n", | |
"\n", | |
" item.appendChild(key);\n", | |
" item.appendChild(value);\n", | |
" legend.appendChild(item);\n", | |
" \n", | |
" data = document.getElementById('legend-points-value-' + p)\n", | |
" data.textContent = myColorStops[p][0];\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"function generateInterpolateExpression(propertyValue, stops) {\n", | |
" var expression;\n", | |
" if (propertyValue == 'zoom') {\n", | |
" expression = ['interpolate', ['exponential', 1.2], ['zoom']]\n", | |
" }\n", | |
" else if (propertyValue == 'heatmap-density') {\n", | |
" expression = ['interpolate', ['linear'], ['heatmap-density']]\n", | |
" }\n", | |
" else {\n", | |
" expression = ['interpolate', ['linear'], ['get', propertyValue]]\n", | |
" }\n", | |
"\n", | |
" for (var i=0; i<stops.length; i++) {\n", | |
" expression.push(stops[i][0], stops[i][1])\n", | |
" }\n", | |
" return expression\n", | |
"}\n", | |
"\n", | |
"\n", | |
"function generateMatchExpression(propertyValue, stops, defaultValue) {\n", | |
" var expression;\n", | |
" expression = ['match', ['get', propertyValue]]\n", | |
" for (var i=0; i<stops.length; i++) {\n", | |
" expression.push(stops[i][0], stops[i][1])\n", | |
" }\n", | |
" expression.push(defaultValue)\n", | |
" \n", | |
" return expression\n", | |
"}\n", | |
"\n", | |
"\n", | |
"function generatePropertyExpression(expressionType, propertyValue, stops, defaultValue) {\n", | |
" var expression;\n", | |
" if (expressionType == 'match') {\n", | |
" expression = generateMatchExpression(propertyValue, stops, defaultValue)\n", | |
" }\n", | |
" else {\n", | |
" expression = generateInterpolateExpression(propertyValue, stops)\n", | |
" }\n", | |
"\n", | |
" return expression\n", | |
"}\n", | |
"\n", | |
"\n", | |
"</script>\n", | |
"\n", | |
"<!-- main map creation code, extended by mapboxgl/templates/choropleth.html -->\n", | |
"<script type='text/javascript'>\n", | |
"\n", | |
"\n", | |
" mapboxgl.accessToken = 'pk.eyJ1IjoicnNiYXVtYW5uIiwiYSI6IjdiOWEzZGIyMGNkOGY3NWQ4ZTBhN2Y5ZGU2Mzg2NDY2In0.jycgv7qwF8MMIWt4cT0RaQ';\n", | |
"\n", | |
" var map = new mapboxgl.Map({\n", | |
" container: 'map',\n", | |
" style: 'mapbox://styles/mapbox/light-v9?optimize=true',\n", | |
" center: [0, 0],\n", | |
" zoom: 0,\n", | |
" pitch: 0,\n", | |
" bearing: 0,\n", | |
" transformRequest: (url, resourceType) => {\n", | |
" if ( url.slice(0,22) == 'https://api.mapbox.com' || \n", | |
" url.slice(0,26) == 'https://a.tiles.mapbox.com' || \n", | |
" url.slice(0,26) == 'https://b.tiles.mapbox.com' ||\n", | |
" url.slice(0,26) == 'https://c.tiles.mapbox.com' ||\n", | |
" url.slice(0,26) == 'https://d.tiles.mapbox.com') {\n", | |
" //Add Mapboxgl-Jupyter Plugin identifier for Mapbox API traffic\n", | |
" return {\n", | |
" url: [url.slice(0, url.indexOf('?')+1), 'pluginName=PythonMapboxgl&', url.slice(url.indexOf('?')+1)].join('')\n", | |
" }\n", | |
" }\n", | |
" else {\n", | |
" //Do not transform URL for non Mapbox GET requests\n", | |
" return {url: url}\n", | |
" }\n", | |
" }\n", | |
" });\n", | |
"\n", | |
" \n", | |
"\n", | |
" map.addControl(new mapboxgl.NavigationControl());\n", | |
"\n", | |
" \n", | |
"\n", | |
" \n", | |
"\n", | |
" var legend = document.getElementById('legend');\n", | |
" \n", | |
" \n", | |
" calcCircleColorLegend([[10000, 'rgb(255,255,204)'], [100000, 'rgb(161,218,180)'], [1000000, 'rgb(65,182,196)'], [10000000, 'rgb(44,127,184)'], [100000000, 'rgb(37,52,148)']], 'pop_est');\n", | |
" \n", | |
"\n", | |
"\n", | |
"\n", | |
" \n", | |
"\n", | |
" map.on('style.load', function() {\n", | |
" \n", | |
" \n", | |
"\n", | |
" // Add geojson data source\n", | |
" map.addSource('data', {\n", | |
" 'type': 'geojson',\n", | |
" 'data': 'pop.geojson',\n", | |
" 'buffer': 1,\n", | |
" 'maxzoom': 14\n", | |
" });\n", | |
"\n", | |
" // Add data layer\n", | |
" map.addLayer({\n", | |
" 'id': 'choropleth-fill',\n", | |
" 'source': 'data',\n", | |
" 'type': 'fill',\n", | |
" 'paint': {\n", | |
" 'fill-color': generatePropertyExpression('interpolate', 'pop_est', [[10000, 'rgb(255,255,204)'], [100000, 'rgb(161,218,180)'], [1000000, 'rgb(65,182,196)'], [10000000, 'rgb(44,127,184)'], [100000000, 'rgb(37,52,148)']], 'grey'),\n", | |
" 'fill-opacity': 1\n", | |
" }\n", | |
" }, 'waterway-label' );\n", | |
"\n", | |
" // Add border layer\n", | |
" map.addLayer({\n", | |
" 'id': 'choropleth-line',\n", | |
" 'source': 'data',\n", | |
" 'type': 'line',\n", | |
" 'layout': {\n", | |
" 'line-join': 'round',\n", | |
" 'line-cap': 'round'\n", | |
" },\n", | |
" 'paint': {\n", | |
" \n", | |
" 'line-dasharray': [1, 0],\n", | |
" \n", | |
" 'line-color': 'white',\n", | |
" 'line-width': 1,\n", | |
" 'line-opacity': 1\n", | |
" }\n", | |
" }, 'waterway-label' );\n", | |
"\n", | |
" // Add label layer\n", | |
" map.addLayer({\n", | |
" 'id': 'choropleth-label',\n", | |
" 'source': 'data',\n", | |
" 'type': 'symbol',\n", | |
" 'layout': {\n", | |
" \n", | |
" 'text-size' : generateInterpolateExpression('zoom', [[0,8],[22,16]] ),\n", | |
" 'text-offset': [0,-1]\n", | |
" },\n", | |
" 'paint': {\n", | |
" 'text-halo-color': 'white',\n", | |
" 'text-halo-width': 1\n", | |
" }\n", | |
" }, 'waterway-label' );\n", | |
"\n", | |
" // Optional extrusion layer\n", | |
" \n", | |
"\n", | |
"\n", | |
" \n", | |
"\n", | |
" // Create a popup\n", | |
" var popup = new mapboxgl.Popup({\n", | |
" closeButton: false,\n", | |
" closeOnClick: false\n", | |
" });\n", | |
" \n", | |
" \n", | |
"\n", | |
" // Show the popup on mouseover\n", | |
" map.on('mousemove', 'choropleth-fill', function(e) {\n", | |
" map.getCanvas().style.cursor = 'pointer';\n", | |
" \n", | |
" let f = e.features[0];\n", | |
" let popup_html = '<div>';\n", | |
"\n", | |
" for (key in f.properties) {\n", | |
" popup_html += '<li><b> ' + key + '</b>: ' + f.properties[key] + ' </li>'\n", | |
" }\n", | |
"\n", | |
" popup_html += '</div>'\n", | |
" popup.setLngLat(e.lngLat)\n", | |
" .setHTML(popup_html)\n", | |
" .addTo(map);\n", | |
" });\n", | |
"\n", | |
" \n", | |
"\n", | |
" map.on('mouseleave', 'choropleth-fill', function() {\n", | |
" map.getCanvas().style.cursor = '';\n", | |
" popup.remove();\n", | |
" });\n", | |
" \n", | |
" // Fly to on click\n", | |
" map.on('click', 'choropleth-fill', function(e) {\n", | |
" map.flyTo({\n", | |
" center: e.lngLat,\n", | |
" zoom: map.getZoom() + 1\n", | |
" });\n", | |
" });\n", | |
"\n", | |
" });\n", | |
"\n", | |
"\n", | |
"\n", | |
"\n", | |
"</script>\n", | |
"\n", | |
"</body>\n", | |
"</html>\" style=\"width: 100%; height: 500px;\"></iframe>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"color_breaks = [10000, 100000, 1000000, 10000000, 100000000]\n", | |
"color_stops = create_color_stops(color_breaks, colors='YlGnBu')\n", | |
"\n", | |
"# Create the viz from the dataframe\n", | |
"viz = ChoroplethViz(data_url,\n", | |
" access_token=token, \n", | |
" color_property = measure,\n", | |
" color_stops = color_stops,\n", | |
" below_layer = 'waterway-label')\n", | |
"\n", | |
"viz.show()" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Conda Py3", | |
"language": "python", | |
"name": "myenv" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment