Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add choropleth support #40

Merged
merged 20 commits into from
Mar 29, 2018
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d3fcd8e
Add basic chloropleth support
Feb 3, 2018
d5a5435
Center zoom on click coordinates; rename polygons layer to 'cholorple…
Feb 19, 2018
07bf5e5
Add line_color, line_stroke, and line_width properties to Chloropleth…
Feb 20, 2018
3a5b3e6
Add chloropleth label layer; add template block for styling legend keys
Feb 20, 2018
bfd6a04
Add line styling to example chloropleth notebook
Feb 27, 2018
6b47dbc
Merge branch 'master' into chloropleth-support
Feb 27, 2018
79fd36a
Update internal documentation in ChloroplethViz class; add chloroplet…
Feb 27, 2018
360ef08
Update spelling to mapbox standard: 'choropleth'
Feb 28, 2018
ac8c100
Add tests for ChoroplethViz (currently uses polygons.geojson)
Feb 28, 2018
f1bcd21
Formatting and headers on choropleth notebook
Mar 2, 2018
9fa3853
Add vector layer support options; requesting direction for reconcilin…
Mar 6, 2018
b11c006
Single ChoroplethViz class defines either vector-based or geojson-bas…
Mar 17, 2018
722d747
Add support for categorical data-driven styling with vector data-join…
Mar 23, 2018
cb9972b
Merge branch 'master' into chloropleth-support; update styleUrl to st…
Mar 23, 2018
07b2ca7
Attempt to add test for utils.rgb_tuple_from_str
Mar 23, 2018
8084c7c
Merge branch 'master' into chloropleth-support
ryanbaumann Mar 27, 2018
cc147a0
Additional test coverage for ChoroplethViz and color_map, rgb_tuple_f…
Mar 29, 2018
29a3c36
Per @ryanbaumann 's comments: revert color data-join style to the old…
Mar 29, 2018
6af2548
Test fix
Mar 29, 2018
d80e99e
Minor refactor to color_map to prioritize returning exact match color…
Mar 29, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs-markdown/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,50 @@ df = pd.read_csv(data_url)
color_breaks = [0,10,100,1000,10000]
color_stops = create_color_stops(color_breaks, colors='YlOrRd')
```

## rgb_tuple_from_str
Convert color represented as a string in format 'rgb(RRR,GGG,BBB)', 'rgba(RRR,GGG,BBB,alpha)', '#RRGGBB' or limited English color name (eg 'red') to tuple of integers from 0 to 255, (RRR, GGG, BBB).

### Params
**rgb_tuple_from_str**(_rgb_string_)

Parameter | Description
--|--
rgb_string | color represented as string in form 'rgb(RRR,GGG,BBB)', 'rgba(RRR,GGG,BBB,alpha)', '#RRGGBB', or limited HTML color names (eg 'red')

### Usage
```python
from mapboxgl.utils import rgb_tuple_from_str

# convert color string to tuple of integers
rgb_tuple_from_str('rgb(255,143,17')
```

## color_map
Convert color represented as a string in format 'rgb(RRR,GGG,BBB)' to tuple of integers from 0 to 255, (RRR, GGG, BBB).

### Params
**color_map**(_lookup, color_stops, default_color='rgb(122,122,122)'_)

Parameter | Description
--|--
lookup | value is numeric for interpolated colors or string for categorical color stops
color_stops | color ramp stops generated from `create_color_stops`, or custom list of numeric or categorical stops with paired colors
default_color | representation of color as hex, RGB, or RGBA strings

### Usage
```python
from mapboxgl.utils import create_color_stops, color_map

# interpolate color for numeric color_stops
color_stops = create_color_stops([0, 50, 100, 500, 1500], colors='YlOrRd')
color = color_map(73, color_stops)

# categorical look up
match_color_stops = [
['Massachusetts', 'rgb(46,204,113)'],
['Utah', 'rgb(231,76,60)'],
['California', 'rgb(142,68,173)'],
]
color = color_map('California', match_color_stops, default_color='grey)')
```
52 changes: 52 additions & 0 deletions docs-markdown/viz.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,55 @@ viz = HeatmapViz('points.geojson',
viz.show()
```
![screen shot 2018-02-21 at 3 34 55 pm](https://user-images.githubusercontent.com/11286381/36511775-cfc4d794-171c-11e8-86b9-5f1a6060a387.png)


## class ChoroplethViz

The `ChoroplethViz` object handles the creation of a choropleth map and inherits from the `MapViz` class. It applies a thematic map style to polygon features with color shading in proportion to the intensity of the data being displayed. Choropleth polygons can be initialized with geojson source or vector source styled using the data-join technique.

### Params
**ChoroplethViz**(_data, vector_url=None, vector_layer_name=None, vector_join_property=None, data_join_property=None, # vector only label_property=None, color_property=None, color_stops=None, color_default='grey', color_function_type='interpolate', line_color='white', line_stroke='solid', line_width=1, *args, **kwargs_)

Parameter | Description | Example
--|--|--
data | can be either GeoJSON (containing polygon features) or JSON for data-join technique with vector polygons |
vector_url | optional property to define vector polygon source | "mapbox://mapbox.us_census_states_2015"
vector_layer_name | property to define target layer of vector source if using vector polygon source | "states"
vector_join_property | property to aid in determining color for styling vector polygons | "STATEFP"
data_join_property | property of json data to use as link to vector features | "state_name"
label_property | property to use for marker label | "density"
color_property | property to determine fill color | "density"
color_stops | property to determine fill color | [[0, "red"], [0.5, "blue"], [1, "green"]]
color_default | property to determine default fill color in match lookups | "#F0F0F0"
color_function_type | property to determine type of expression used by Mapbox to assign color | "interpolate"
line_color | property to determine choropleth border line color | "#FFFFFF"
line_stroke | property to determine choropleth border line stroke (one of solid (-), dashed (--), dotted (:), dash dot (-.)) | "solid" or "-"
line_width | property to determine choropleth border line width | 1

[View options](https://github.com/mapbox/mapboxgl-jupyter/blob/master/docs-markdown/viz.md#params)

### Usage
```python
import os
from mapboxgl.viz import *
from mapboxgl.utils import *

# Must be a public token, starting with `pk`
token = os.getenv('MAPBOX_ACCESS_TOKEN')

# Create Choropleth with GeoJSON Source
viz = ChoroplethViz('us-states.geojson',
color_property='density',
color_stops=create_color_stops([0, 50, 100, 500, 1500], colors='YlOrRd'),
color_function_type='interpolate',
line_stroke='--',
line_color='rgb(128,0,38)',
line_width=1,
opacity=0.8,
center=(-96, 37.8),
zoom=3,
below_layer='waterway-label'
)
viz.show()
```
![screen shot 2018-02-26 at 4 54 59 pm](https://user-images.githubusercontent.com/13527707/36704653-186bb2e0-1b16-11e8-9dac-2d929e678be9.png)
191 changes: 191 additions & 0 deletions examples/choropleth-viz-example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Mapboxgl Python Library\n",
"\n",
"https://github.com/mapbox/mapboxgl-jupyter"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from mapboxgl.viz import *\n",
"from mapboxgl.utils import *\n",
"\n",
"# Must be a public token, starting with `pk`\n",
"token = os.getenv('MAPBOX_ACCESS_TOKEN')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Choropleths with interpolated color assignment from GeoJSON source"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"# create choropleth from polygon features stored as GeoJSON\n",
"viz = ChoroplethViz('us-states.geojson', \n",
" color_property='density',\n",
" color_stops=create_color_stops([0, 50, 100, 500, 1500], colors='YlOrRd'),\n",
" color_function_type='interpolate',\n",
" line_stroke='--',\n",
" line_color='rgb(128,0,38)',\n",
" line_width=1,\n",
" opacity=0.8,\n",
" center=(-96, 37.8),\n",
" zoom=3,\n",
" below_layer='waterway-label'\n",
" )\n",
"viz.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Choropleths with match-type color scheme from GeoJSON source"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"match_color_stops = [\n",
" ['Massachusetts', 'rgb(46,204,113)'],\n",
" ['Utah', 'rgb(231,76,60)'],\n",
" ['California', 'rgb(142,68,173)'],\n",
"]\n",
"\n",
"viz = ChoroplethViz('us-states.geojson', \n",
" color_property='name', \n",
" color_stops = match_color_stops, \n",
" color_function_type = 'match', \n",
" color_default = 'rgba(52,73,94,0.5)', \n",
" opacity=0.8, \n",
" center = (-96, 37.8), \n",
" zoom = 3, \n",
" below_layer = 'waterway-label'\n",
" )\n",
"viz.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vector polygon source with data-join technique\n",
"\n",
"In this configuration, properties in JSON data are used to calculate colors to style polygons from the vector source."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# must be JSON object (need to extend to use referenced JSON file)\n",
"data = [{\"id\": \"01\", \"name\": \"Alabama\", \"density\": 94.65}, {\"id\": \"02\", \"name\": \"Alaska\", \"density\": 1.264}, {\"id\": \"04\", \"name\": \"Arizona\", \"density\": 57.05}, {\"id\": \"05\", \"name\": \"Arkansas\", \"density\": 56.43}, {\"id\": \"06\", \"name\": \"California\", \"density\": 241.7}, {\"id\": \"08\", \"name\": \"Colorado\", \"density\": 49.33}, {\"id\": \"09\", \"name\": \"Connecticut\", \"density\": 739.1}, {\"id\": \"10\", \"name\": \"Delaware\", \"density\": 464.3}, {\"id\": \"11\", \"name\": \"District of Columbia\", \"density\": 10065}, {\"id\": \"12\", \"name\": \"Florida\", \"density\": 353.4}, {\"id\": \"13\", \"name\": \"Georgia\", \"density\": 169.5}, {\"id\": \"15\", \"name\": \"Hawaii\", \"density\": 214.1}, {\"id\": \"16\", \"name\": \"Idaho\", \"density\": 19.15}, {\"id\": \"17\", \"name\": \"Illinois\", \"density\": 231.5}, {\"id\": \"18\", \"name\": \"Indiana\", \"density\": 181.7}, {\"id\": \"19\", \"name\": \"Iowa\", \"density\": 54.81}, {\"id\": \"20\", \"name\": \"Kansas\", \"density\": 35.09}, {\"id\": \"21\", \"name\": \"Kentucky\", \"density\": 110}, {\"id\": \"22\", \"name\": \"Louisiana\", \"density\": 105}, {\"id\": \"23\", \"name\": \"Maine\", \"density\": 43.04}, {\"id\": \"24\", \"name\": \"Maryland\", \"density\": 596.3}, {\"id\": \"25\", \"name\": \"Massachusetts\", \"density\": 840.2}, {\"id\": \"26\", \"name\": \"Michigan\", \"density\": 173.9}, {\"id\": \"27\", \"name\": \"Minnesota\", \"density\": 67.14}, {\"id\": \"28\", \"name\": \"Mississippi\", \"density\": 63.5}, {\"id\": \"29\", \"name\": \"Missouri\", \"density\": 87.26}, {\"id\": \"30\", \"name\": \"Montana\", \"density\": 6.858}, {\"id\": \"31\", \"name\": \"Nebraska\", \"density\": 23.97}, {\"id\": \"32\", \"name\": \"Nevada\", \"density\": 24.8}, {\"id\": \"33\", \"name\": \"New Hampshire\", \"density\": 147}, {\"id\": \"34\", \"name\": \"New Jersey\", \"density\": 1189}, {\"id\": \"35\", \"name\": \"New Mexico\", \"density\": 17.16}, {\"id\": \"36\", \"name\": \"New York\", \"density\": 412.3}, {\"id\": \"37\", \"name\": \"North Carolina\", \"density\": 198.2}, {\"id\": \"38\", \"name\": \"North Dakota\", \"density\": 9.916}, {\"id\": \"39\", \"name\": \"Ohio\", \"density\": 281.9}, {\"id\": \"40\", \"name\": \"Oklahoma\", \"density\": 55.22}, {\"id\": \"41\", \"name\": \"Oregon\", \"density\": 40.33}, {\"id\": \"42\", \"name\": \"Pennsylvania\", \"density\": 284.3}, {\"id\": \"44\", \"name\": \"Rhode Island\", \"density\": 1006}, {\"id\": \"45\", \"name\": \"South Carolina\", \"density\": 155.4}, {\"id\": \"46\", \"name\": \"South Dakota\", \"density\": 98.07}, {\"id\": \"47\", \"name\": \"Tennessee\", \"density\": 88.08}, {\"id\": \"48\", \"name\": \"Texas\", \"density\": 98.07}, {\"id\": \"49\", \"name\": \"Utah\", \"density\": 34.3}, {\"id\": \"50\", \"name\": \"Vermont\", \"density\": 67.73}, {\"id\": \"51\", \"name\": \"Virginia\", \"density\": 204.5}, {\"id\": \"53\", \"name\": \"Washington\", \"density\": 102.6}, {\"id\": \"54\", \"name\": \"West Virginia\", \"density\": 77.06}, {\"id\": \"55\", \"name\": \"Wisconsin\", \"density\": 105.2}, {\"id\": \"56\", \"name\": \"Wyoming\", \"density\": 5.851}, {\"id\": \"72\", \"name\": \"Puerto Rico\", \"density\": 1082}]\n",
"\n",
"# create choropleth map with vector source styling use data in JSON object\n",
"viz = ChoroplethViz(data, \n",
" vector_url='mapbox://mapbox.us_census_states_2015',\n",
" vector_layer_name='states',\n",
" vector_join_property='STATEFP',\n",
" data_join_property='id',\n",
" color_property='density',\n",
" color_stops=create_color_stops([0, 50, 100, 500, 1500], colors='YlOrRd'),\n",
" line_stroke='dashed',\n",
" line_color='rgb(128,0,38)',\n",
" opacity=0.8,\n",
" center=(-96, 37.8),\n",
" zoom=3,\n",
" below_layer='waterway-label'\n",
" )\n",
"viz.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Vector polygon source with data-join technique, categorical color scheme"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# must be JSON object (need to extend to use referenced JSON file)\n",
"data = [{\"id\": \"01\", \"name\": \"Alabama\", \"density\": 94.65}, {\"id\": \"02\", \"name\": \"Alaska\", \"density\": 1.264}, {\"id\": \"04\", \"name\": \"Arizona\", \"density\": 57.05}, {\"id\": \"05\", \"name\": \"Arkansas\", \"density\": 56.43}, {\"id\": \"06\", \"name\": \"California\", \"density\": 241.7}, {\"id\": \"08\", \"name\": \"Colorado\", \"density\": 49.33}, {\"id\": \"09\", \"name\": \"Connecticut\", \"density\": 739.1}, {\"id\": \"10\", \"name\": \"Delaware\", \"density\": 464.3}, {\"id\": \"11\", \"name\": \"District of Columbia\", \"density\": 10065}, {\"id\": \"12\", \"name\": \"Florida\", \"density\": 353.4}, {\"id\": \"13\", \"name\": \"Georgia\", \"density\": 169.5}, {\"id\": \"15\", \"name\": \"Hawaii\", \"density\": 214.1}, {\"id\": \"16\", \"name\": \"Idaho\", \"density\": 19.15}, {\"id\": \"17\", \"name\": \"Illinois\", \"density\": 231.5}, {\"id\": \"18\", \"name\": \"Indiana\", \"density\": 181.7}, {\"id\": \"19\", \"name\": \"Iowa\", \"density\": 54.81}, {\"id\": \"20\", \"name\": \"Kansas\", \"density\": 35.09}, {\"id\": \"21\", \"name\": \"Kentucky\", \"density\": 110}, {\"id\": \"22\", \"name\": \"Louisiana\", \"density\": 105}, {\"id\": \"23\", \"name\": \"Maine\", \"density\": 43.04}, {\"id\": \"24\", \"name\": \"Maryland\", \"density\": 596.3}, {\"id\": \"25\", \"name\": \"Massachusetts\", \"density\": 840.2}, {\"id\": \"26\", \"name\": \"Michigan\", \"density\": 173.9}, {\"id\": \"27\", \"name\": \"Minnesota\", \"density\": 67.14}, {\"id\": \"28\", \"name\": \"Mississippi\", \"density\": 63.5}, {\"id\": \"29\", \"name\": \"Missouri\", \"density\": 87.26}, {\"id\": \"30\", \"name\": \"Montana\", \"density\": 6.858}, {\"id\": \"31\", \"name\": \"Nebraska\", \"density\": 23.97}, {\"id\": \"32\", \"name\": \"Nevada\", \"density\": 24.8}, {\"id\": \"33\", \"name\": \"New Hampshire\", \"density\": 147}, {\"id\": \"34\", \"name\": \"New Jersey\", \"density\": 1189}, {\"id\": \"35\", \"name\": \"New Mexico\", \"density\": 17.16}, {\"id\": \"36\", \"name\": \"New York\", \"density\": 412.3}, {\"id\": \"37\", \"name\": \"North Carolina\", \"density\": 198.2}, {\"id\": \"38\", \"name\": \"North Dakota\", \"density\": 9.916}, {\"id\": \"39\", \"name\": \"Ohio\", \"density\": 281.9}, {\"id\": \"40\", \"name\": \"Oklahoma\", \"density\": 55.22}, {\"id\": \"41\", \"name\": \"Oregon\", \"density\": 40.33}, {\"id\": \"42\", \"name\": \"Pennsylvania\", \"density\": 284.3}, {\"id\": \"44\", \"name\": \"Rhode Island\", \"density\": 1006}, {\"id\": \"45\", \"name\": \"South Carolina\", \"density\": 155.4}, {\"id\": \"46\", \"name\": \"South Dakota\", \"density\": 98.07}, {\"id\": \"47\", \"name\": \"Tennessee\", \"density\": 88.08}, {\"id\": \"48\", \"name\": \"Texas\", \"density\": 98.07}, {\"id\": \"49\", \"name\": \"Utah\", \"density\": 34.3}, {\"id\": \"50\", \"name\": \"Vermont\", \"density\": 67.73}, {\"id\": \"51\", \"name\": \"Virginia\", \"density\": 204.5}, {\"id\": \"53\", \"name\": \"Washington\", \"density\": 102.6}, {\"id\": \"54\", \"name\": \"West Virginia\", \"density\": 77.06}, {\"id\": \"55\", \"name\": \"Wisconsin\", \"density\": 105.2}, {\"id\": \"56\", \"name\": \"Wyoming\", \"density\": 5.851}, {\"id\": \"72\", \"name\": \"Puerto Rico\", \"density\": 1082}]\n",
"\n",
"match_color_stops = [\n",
" ['Massachusetts', 'rgb(46,204,113)'],\n",
" ['Utah', 'rgb(231,76,60)'],\n",
" ['California', 'rgb(142,68,173)'],\n",
"]\n",
"\n",
"# create choropleth map with vector source styling use data in JSON object\n",
"viz = ChoroplethViz(data, \n",
" vector_url='mapbox://mapbox.us_census_states_2015',\n",
" vector_layer_name='states',\n",
" vector_join_property='STATEFP',\n",
" data_join_property='id',\n",
" color_property='name',\n",
" color_stops=match_color_stops,\n",
" color_default = 'rgba(52,73,94,0.5)', \n",
" opacity=0.8,\n",
" center=(-96, 37.8),\n",
" zoom=3,\n",
" below_layer='waterway-label'\n",
" )\n",
"viz.show()"
]
}
],
"metadata": {
"anaconda-cloud": {
"attach-environment": true,
"environment": "Root",
"summary": "Mapboxgl Python Data Visualization example"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
1 change: 1 addition & 0 deletions examples/us-states.geojson

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions mapboxgl/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,21 @@
12: ['rgb(141,211,199)', 'rgb(255,255,179)', 'rgb(190,186,218)', 'rgb(251,128,114)', 'rgb(128,177,211)', 'rgb(253,180,98)', 'rgb(179,222,105)', 'rgb(252,205,229)', 'rgb(217,217,217)', 'rgb(188,128,189)', 'rgb(204,235,197)', 'rgb(255,237,111)']
}
)

# a few HTML / X11 color names
common_html_colors = {
'red': 'rgb(255,0,0)',
'orange': 'rgb(255,165,0)',
'yellow': 'rgb(255,255,0)',
'green': 'rgb(0,128,0)',
'blue': 'rgb(0,0,255)',
'purple': 'rgb(128,0,128)',
'pink': 'rgb(255,192,203)',
'white': 'rgb(255,255,255)',
'grey': 'rgb(128,128,128)',
'gray': 'rgb(128,128,128)',
'black': 'rgb(0,0,0)',
'brown': 'rgb(139,69,19)',
'magenta': 'rgb(255,0,255)',
'cyan': 'rgb(0,255,255)',
}
Loading