From 4600bc2a257933352349c777bf5405565c866f22 Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Fri, 21 Feb 2020 11:24:34 -0500 Subject: [PATCH 1/8] choropleth mapbox --- r/2020-01-30-choropleth-rmapbox.Rmd | 146 ++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 r/2020-01-30-choropleth-rmapbox.Rmd diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd new file mode 100644 index 00000000..f5cbaff3 --- /dev/null +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -0,0 +1,146 @@ +--- +description: How to make a Mapbox Choropleth Map of US Counties in R with Plotly. +display_as: maps +language: r +layout: base +name: Choropleth mapbox +order: 12 +output: + html_document: + keep_md: true +page_type: u-guide +permalink: r/mapbox-county-choropleth/ +thumbnail: thumbnail/mapbox-choropleth.png +--- + +```{r, echo = FALSE, message=FALSE} +knitr::opts_chunk$set(message = FALSE, warning=FALSE) +``` + +A [Choropleth Map](https://en.wikipedia.org/wiki/Choropleth_map) is a map composed of colored polygons. It is used to represent spatial variations of a quantity. This page documents how to build **tile-map** choropleth maps, but you can also build [**outline** choropleth maps using our non-Mapbox trace types](/r/choropleth-maps). + +Below we show how to create Choropleth Maps using Plotly `Choroplethmapbox` graph object. + +### Mapbox Access Token and Base Map Configuration + +To plot on Mapbox maps with Plotly you *may* need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Map Layers](/r/mapbox-layers/) documentation for more information. If you're using a Chart Studio Enterprise server, please see additional instructions [here](https://help.plot.ly/mapbox-atlas). + +### Introduction: main parameters for choropleth tile maps + +Making choropleth Mapbox maps requires two main types of input: + +1. GeoJSON-formatted geometry information where each feature has either an `id` field or some identifying value in `properties`. +2. A list of values indexed by feature identifier. + +The GeoJSON data is passed to the `geojson` argument, and the data is passed into the `color` argument of `px.choropleth_mapbox` (`z` if using `graph_objects`), in the same order as the IDs are passed into the `location` argument. + +**Note** the `geojson` attribute can also be the URL to a GeoJSON file, which can speed up map rendering in certain cases. + +#### GeoJSON with `feature.id` + +Here we load a GeoJSON file containing the geometry information for US counties, where `feature.id` is a [FIPS code](https://en.wikipedia.org/wiki/FIPS_county_code). + +```{r} +library(jsonlite) +json_file <- fromJSON('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') +counties <- as.data.frame(json_file) +counties <- counties[,-1] +a <- counties[1,] +``` + +### Data indexed by `id` + +Here we load unemployment data by county, also indexed by [FIPS code](https://en.wikipedia.org/wiki/FIPS_county_code). + +```{r} +df = read.csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv", header = T, colClasses = c("fips"="character")) +head(df) +``` + +### Choropleth map using carto base map (no token needed) + +With `choroplethmapbox`, each row of the DataFrame is represented as a region of the choropleth. + +```{r} +library(rjson) +library(plotly) +library(data.table) + +url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' +counties <- rjson::fromJSON(file = url) +url2<- "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" +mydat <- fread(url2,colClasses = c(fips = "character")) +fig <- plot_ly() %>% + add_trace( + type = "choroplethmapbox", + mydat, + geojson = counties, + locations = mydat$fips, + z=mydat$unemp, + colorscale="Viridis", + zmin=0, + zmax=12, + marker=list(line = list( + width = 0), + opacity=0.5 + ) + ) %>% + layout( + mapbox = list( + style = "carto-positron", + zoom =3, + center = list(lon = -95.7129, lat = 37.0902)) + ) +fig +``` +### Indexing by GeoJSON Properties + +If the GeoJSON you are using either does not have an `id` field or you wish you use one of the keys in the `properties` field, you may use the `featureidkey` parameter to specify where to match the values of `id`. +In the following GeoJSON object/data-file pairing, the values of `properties.feature.id` match the values of the `feature.id` column: + +```{r} +json_file$features$id[1] +counties$features.id[1] +``` +#### Mapbox Light base map: free token needed + +```{r} +library(rjson) +library(plotly) +library(data.table) + +mapboxToken <- paste(readLines(".mapbox_token"), collapse="") # You need your own token +Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca + +url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' +counties <- rjson::fromJSON(file = url) +url2<- "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" +mydat <- fread(url2,colClasses = c(fips = "character")) + +fig <- plot_ly() +fig <- fig %>% add_trace( + type = "choroplethmapbox", + mydat, + geojson = counties, + locations = mydat$fips, + z=mydat$unemp, + colorscale="Viridis", + zmin=0, + zmax=12, + marker=list(line = list( + width = 0), + opacity=0.5 + ) + ) +fig <- fig %>% layout( + mapbox = list( + style = "light", + zoom =3, + center = list(lon = -95.7129, lat = 37.0902)) + ) +fig <- fig %>% config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN")) +fig +``` +#Reference + +See [https://plot.ly/r/reference/#scattermapbox](https://plot.ly/r/reference/#scattermapbox) for more information and options! \ No newline at end of file From 25a83f41768d505ff947f7d28de2223dd03e0dfc Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Mon, 24 Feb 2020 19:24:21 -0500 Subject: [PATCH 2/8] fixup path for mapbox_token --- r/2020-01-30-choropleth-rmapbox.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index f5cbaff3..22999e7c 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -109,7 +109,7 @@ library(rjson) library(plotly) library(data.table) -mapboxToken <- paste(readLines(".mapbox_token"), collapse="") # You need your own token +mapboxToken <- paste(readLines("../.mapbox_token"), collapse="") # You need your own token Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' From 5b8a6ce7054beddf28c2d2487d067ed4b227ac31 Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Tue, 25 Feb 2020 08:19:53 -0500 Subject: [PATCH 3/8] changing the order --- r/2020-01-30-choropleth-rmapbox.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index 22999e7c..a0dc5b09 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -4,7 +4,7 @@ display_as: maps language: r layout: base name: Choropleth mapbox -order: 12 +order: 13 output: html_document: keep_md: true From b7a99a048ceb1d93b342315a8bbc1ce6971b4269 Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Fri, 28 Feb 2020 15:09:19 -0500 Subject: [PATCH 4/8] refactoring for the sake of consistency --- r/2017-04-12-county-level-choropleth.Rmd | 140 +---------------------- r/2020-01-30-choropleth-rmapbox.Rmd | 89 +++++++------- 2 files changed, 40 insertions(+), 189 deletions(-) diff --git a/r/2017-04-12-county-level-choropleth.Rmd b/r/2017-04-12-county-level-choropleth.Rmd index 76235e5f..a85e952c 100644 --- a/r/2017-04-12-county-level-choropleth.Rmd +++ b/r/2017-04-12-county-level-choropleth.Rmd @@ -10,144 +10,6 @@ output: keep_md: true permalink: r/county-level-choropleth/ thumbnail: thumbnail/county-level-choropleth.jpg +redirect_to: r/mapbox-county-choropleth/ --- -```{r, echo = FALSE, message=FALSE} -knitr::opts_chunk$set(message = FALSE, warning=FALSE) -``` -### Mapbox Access Token - -To plot on Mapbox maps with Plotly you *may* need a Mapbox account and a public [Mapbox Access Token](https://www.mapbox.com/studio). See our [Mapbox Mafig Layers](/r/mapbox-layers/) documentation for more information. If you're using a Chart Studio Enterprise server, please see additional instructions [here](https://help.plot.ly/mapbox-atlas). - -### Creating Polygon Boundaries - -```{r} -library(plotly) - -blank_layer <- list( - title = "", - showgrid = F, - showticklabels = F, - zeroline = F) - -fig <- map_data("county") -fig <- fig %>% filter(region == 'california') -fig <- fig %>% group_by(group) -fig <- fig %>% plot_ly( - x = ~long, - y = ~lat, - fillcolor = 'white', - hoverinfo = "none") -fig <- fig %>% add_polygons( - line = list(color = 'black', width = 0.5)) -fig <- fig %>% layout( - xaxis = blank_layer, - yaxis = blank_layer) - -fig -``` - -### Add County-Level Data - -```{r} -library(tidyverse) -library(plotly) - -df <- read.csv("https://raw.githubusercontent.com/bcdunbar/datasets/master/californiaPopulation.csv") - -cali <- map_data("county") -cali <- cali %>% filter(region == 'california') - -pop <- df -pop <- pop %>% group_by(County.Name) -pop <- pop %>% summarise(Pop = sum(Population)) - -pop$County.Name <- tolower(pop$County.Name) # matching string - -cali_pop <- merge(cali, pop, by.x = "subregion", by.y = "County.Name") - -cali_pop$pop_cat <- cut(cali_pop$Pop, breaks = c(seq(0, 11000000, by = 500000)), labels=1:22) - -fig <- cali_pop -fig <- fig %>% group_by(group) -fig <- fig %>% plot_ly(x = ~long, y = ~lat, color = ~pop_cat, colors = c('#ffeda0','#f03b20'), - text = ~subregion, hoverinfo = 'text') -fig <- fig %>% add_polygons(line = list(width = 0.4)) -fig <- fig %>% add_polygons( - fillcolor = 'transparent', - line = list(color = 'black', width = 0.5), - showlegend = FALSE, hoverinfo = 'none' - ) -fig <- fig %>% layout( - title = "California Population by County", - titlefont = list(size = 10), - xaxis = list(title = "", showgrid = FALSE, - zeroline = FALSE, showticklabels = FALSE), - yaxis = list(title = "", showgrid = FALSE, - zeroline = FALSE, showticklabels = FALSE) - ) - -fig -``` - -### Add Polygon to a Map Projection - -```{r} -library(plotly) - -geo <- list( - scope = 'usa', - showland = TRUE, - landcolor = toRGB("gray95"), - countrycolor = toRGB("gray80") -) - -fig <- cali_pop -fig <- fig %>% group_by(group) -fig <- fig %>% plot_geo( - x = ~long, y = ~lat, color = ~pop_cat, colors = c('#ffeda0','#f03b20'), - text = ~subregion, hoverinfo = 'text') -fig <- fig %>% add_polygons(line = list(width = 0.4)) -fig <- fig %>% add_polygons( - fillcolor = 'transparent', - line = list(color = 'black', width = 0.5), - showlegend = FALSE, hoverinfo = 'none' - ) -fig <- fig %>% layout( - title = "California Population by County", - geo = geo) - -fig -``` - -### Add Polygon to Mapbox -```{r} -library(plotly) - -mapboxToken <- paste(readLines("../.mapbox_token"), collapse="") # You need your own token -Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca - -fig <- cali_pop -fig <- fig %>% group_by(group) -fig <- fig %>% plot_mapbox(x = ~long, y = ~lat, color = ~pop_cat, colors = c('#ffeda0','#f03b20'), - text = ~subregion, hoverinfo = 'text', showlegend = FALSE) -fig <- fig %>% add_polygons( - line = list(width = 0.4) - ) -fig <- fig %>% add_polygons(fillcolor = 'transparent', - line = list(color = 'black', width = 0.5), - showlegend = FALSE, hoverinfo = 'none' - ) -fig <- fig %>% layout( - xaxis = list(title = "", showgrid = FALSE, showticklabels = FALSE), - yaxis = list(title = "", showgrid = FALSE, showticklabels = FALSE), - mapbox = list( - style = 'light', - zoom = 4, - center = list(lat = ~median(lat), lon = ~median(long))), - margin = list(l = 0, r = 0, b = 0, t = 0, pad = 0) - ) -fig <- fig %>% config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN")) - -fig -``` \ No newline at end of file diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index a0dc5b09..db49600f 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -41,11 +41,11 @@ The GeoJSON data is passed to the `geojson` argument, and the data is passed int Here we load a GeoJSON file containing the geometry information for US counties, where `feature.id` is a [FIPS code](https://en.wikipedia.org/wiki/FIPS_county_code). ```{r} -library(jsonlite) -json_file <- fromJSON('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') -counties <- as.data.frame(json_file) -counties <- counties[,-1] -a <- counties[1,] +library(rjson) +url = 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' +json_file <- rjson::fromJSON(file=url) +json_file$features[1] +counties$features[[1]]$id ``` ### Data indexed by `id` @@ -67,41 +67,31 @@ library(plotly) library(data.table) url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' -counties <- rjson::fromJSON(file = url) +counties <- rjson::fromJSON(file=url) url2<- "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" -mydat <- fread(url2,colClasses = c(fips = "character")) -fig <- plot_ly() %>% - add_trace( - type = "choroplethmapbox", - mydat, - geojson = counties, - locations = mydat$fips, - z=mydat$unemp, +df <- read.csv(url2, colClasses=c(fips="character")) +fig <- plot_ly() +fig <- fig %>% add_trace( + type="choroplethmapbox", + geojson=counties, + locations=df$fips, + z=df$unemp, colorscale="Viridis", zmin=0, zmax=12, - marker=list(line = list( - width = 0), + marker=list(line=list( + width=0), opacity=0.5 ) - ) %>% - layout( - mapbox = list( - style = "carto-positron", - zoom =3, - center = list(lon = -95.7129, lat = 37.0902)) + ) +fig <- fig %>% layout( + mapbox=list( + style="carto-positron", + zoom =2, + center=list(lon= -95.71, lat=37.09)) ) fig ``` -### Indexing by GeoJSON Properties - -If the GeoJSON you are using either does not have an `id` field or you wish you use one of the keys in the `properties` field, you may use the `featureidkey` parameter to specify where to match the values of `id`. -In the following GeoJSON object/data-file pairing, the values of `properties.feature.id` match the values of the `feature.id` column: - -```{r} -json_file$features$id[1] -counties$features.id[1] -``` #### Mapbox Light base map: free token needed ```{r} @@ -109,35 +99,34 @@ library(rjson) library(plotly) library(data.table) -mapboxToken <- paste(readLines("../.mapbox_token"), collapse="") # You need your own token +mapboxToken <- paste(readLines(".mapbox_token"), collapse="") # You need your own token Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' counties <- rjson::fromJSON(file = url) url2<- "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" -mydat <- fread(url2,colClasses = c(fips = "character")) +df <- read.csv(url2,colClasses = c(fips = "character")) fig <- plot_ly() fig <- fig %>% add_trace( - type = "choroplethmapbox", - mydat, - geojson = counties, - locations = mydat$fips, - z=mydat$unemp, - colorscale="Viridis", - zmin=0, - zmax=12, - marker=list(line = list( - width = 0), - opacity=0.5 - ) + type = "choroplethmapbox", + geojson = counties, + locations = df$fips, + z=df$unemp, + colorscale="Viridis", + zmin=0, + zmax=12, + marker=list(line = list( + width = 0), + opacity=0.5 ) +) fig <- fig %>% layout( - mapbox = list( - style = "light", - zoom =3, - center = list(lon = -95.7129, lat = 37.0902)) - ) + mapbox = list( + style = "light", + zoom =3, + center = list(lon = -95.7129, lat = 37.0902)) +) fig <- fig %>% config(mapboxAccessToken = Sys.getenv("MAPBOX_TOKEN")) fig ``` From 90a6fa0d03d69c162519efd9cd17d900554e7715 Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Fri, 28 Feb 2020 15:33:04 -0500 Subject: [PATCH 5/8] fix ci --- r/2020-01-30-choropleth-rmapbox.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index db49600f..1fa413ed 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -45,7 +45,7 @@ library(rjson) url = 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' json_file <- rjson::fromJSON(file=url) json_file$features[1] -counties$features[[1]]$id +json_file$features[[1]]$id ``` ### Data indexed by `id` From 0d486f030d16aed4a313c94efbaea9c5ad0b2d09 Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Fri, 28 Feb 2020 16:07:35 -0500 Subject: [PATCH 6/8] mapbox token --- r/2020-01-30-choropleth-rmapbox.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index 1fa413ed..a197bee7 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -99,7 +99,7 @@ library(rjson) library(plotly) library(data.table) -mapboxToken <- paste(readLines(".mapbox_token"), collapse="") # You need your own token +mapboxToken <- paste(readLines("../.mapbox_token"), collapse="") # You need your own token Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' From e3789dc0b525f1692d06b04dcc0a3c39834133ff Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Sun, 1 Mar 2020 13:44:22 -0500 Subject: [PATCH 7/8] minor revision --- r/2017-04-12-county-level-choropleth.Rmd | 15 --------------- r/2020-01-30-choropleth-rmapbox.Rmd | 6 ++---- 2 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 r/2017-04-12-county-level-choropleth.Rmd diff --git a/r/2017-04-12-county-level-choropleth.Rmd b/r/2017-04-12-county-level-choropleth.Rmd deleted file mode 100644 index a85e952c..00000000 --- a/r/2017-04-12-county-level-choropleth.Rmd +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: How to create county-level choropleths in R with Plotly. -display_as: maps -language: r -layout: base -name: County Level Choropleth -order: 8 -output: - html_document: - keep_md: true -permalink: r/county-level-choropleth/ -thumbnail: thumbnail/county-level-choropleth.jpg -redirect_to: r/mapbox-county-choropleth/ ---- - diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index a197bee7..b1e96472 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -11,6 +11,7 @@ output: page_type: u-guide permalink: r/mapbox-county-choropleth/ thumbnail: thumbnail/mapbox-choropleth.png +redirect_from: r/county-level-choropleth/ --- ```{r, echo = FALSE, message=FALSE} @@ -56,7 +57,6 @@ Here we load unemployment data by county, also indexed by [FIPS code](https://en df = read.csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv", header = T, colClasses = c("fips"="character")) head(df) ``` - ### Choropleth map using carto base map (no token needed) With `choroplethmapbox`, each row of the DataFrame is represented as a region of the choropleth. @@ -64,7 +64,6 @@ With `choroplethmapbox`, each row of the DataFrame is represented as a region of ```{r} library(rjson) library(plotly) -library(data.table) url <- 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' counties <- rjson::fromJSON(file=url) @@ -97,7 +96,6 @@ fig ```{r} library(rjson) library(plotly) -library(data.table) mapboxToken <- paste(readLines("../.mapbox_token"), collapse="") # You need your own token Sys.setenv("MAPBOX_TOKEN" = mapboxToken) # for Orca @@ -132,4 +130,4 @@ fig ``` #Reference -See [https://plot.ly/r/reference/#scattermapbox](https://plot.ly/r/reference/#scattermapbox) for more information and options! \ No newline at end of file +See [https://plot.ly/r/reference/#scattermapbox](https://plot.ly/r/reference/#choroplethmapbox) for more information and options! \ No newline at end of file From ddbe4b2f111c62e33cfbd1f8be7b546bc096d8ca Mon Sep 17 00:00:00 2001 From: mahdis-z Date: Sun, 1 Mar 2020 14:26:02 -0500 Subject: [PATCH 8/8] fix ci --- r/2020-01-30-choropleth-rmapbox.Rmd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/r/2020-01-30-choropleth-rmapbox.Rmd b/r/2020-01-30-choropleth-rmapbox.Rmd index b1e96472..b2849e89 100644 --- a/r/2020-01-30-choropleth-rmapbox.Rmd +++ b/r/2020-01-30-choropleth-rmapbox.Rmd @@ -4,7 +4,7 @@ display_as: maps language: r layout: base name: Choropleth mapbox -order: 13 +order: 8 output: html_document: keep_md: true @@ -45,7 +45,6 @@ Here we load a GeoJSON file containing the geometry information for US counties, library(rjson) url = 'https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json' json_file <- rjson::fromJSON(file=url) -json_file$features[1] json_file$features[[1]]$id ```