Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ryanbaumann/ce718be93056f7810072950975777dda to your computer and use it in GitHub Desktop.
Save ryanbaumann/ce718be93056f7810072950975777dda to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
{
"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