Choropleth Maps in R
How to make a choropleth map in R. A choropleth map shades geographic regions by value.
Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Try Plotly Studio now.
Note: We are retiring documentation for R, MATLAB, Julia, and F# in November 2025. Learn more about this change here.
A 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 outline choropleth maps, but you can also build choropleth tile maps using our Mapbox trace types.
Base Map Configuration
Plotly figures made with plot_ly have a layout.geo object which can be used to control the appearance of the base map onto which data is plotted.
Introduction: main parameters for choropleth outline maps
Making choropleth maps requires two main types of input:
- Geometry information:
- This can either be a supplied GeoJSON file where each feature has either an
idfield or some identifying value inproperties; or - one of the built-in geometries within
plot_ly: US states and world countries (see below)
- This can either be a supplied GeoJSON file where each feature has either an
- A list of values indexed by feature identifier.
The GeoJSON data is passed to the geojson argument, and the data is passed into the z argument of choropleth traces.
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.
library(plotly)
library(rjson)
data <- fromJSON(file="https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json")
data$features[[1]]
## $type
## [1] "Feature"
##
## $properties
## $properties$GEO_ID
## [1] "0500000US01001"
##
## $properties$STATE
## [1] "01"
##
## $properties$COUNTY
## [1] "001"
##
## $properties$NAME
## [1] "Autauga"
##
## $properties$LSAD
## [1] "County"
##
## $properties$CENSUSAREA
## [1] 594.436
##
##
## $geometry
## $geometry$type
## [1] "Polygon"
##
## $geometry$coordinates
## $geometry$coordinates[[1]]
## $geometry$coordinates[[1]][[1]]
## [1] -86.49677 32.34444
##
## $geometry$coordinates[[1]][[2]]
## [1] -86.71790 32.40281
##
## $geometry$coordinates[[1]][[3]]
## [1] -86.81491 32.34080
##
## $geometry$coordinates[[1]][[4]]
## [1] -86.89058 32.50297
##
## $geometry$coordinates[[1]][[5]]
## [1] -86.91760 32.66417
##
## $geometry$coordinates[[1]][[6]]
## [1] -86.71339 32.66173
##
## $geometry$coordinates[[1]][[7]]
## [1] -86.71422 32.70569
##
## $geometry$coordinates[[1]][[8]]
## [1] -86.41312 32.70739
##
## $geometry$coordinates[[1]][[9]]
## [1] -86.41117 32.40994
##
## $geometry$coordinates[[1]][[10]]
## [1] -86.49677 32.34444
##
##
##
##
## $id
## [1] "01001"
Data indexed by id
Here we load unemployment data by county, also indexed by FIPS code.
df = read.csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv", header = T, colClasses = c("fips"="character"))
head(df)
## fips unemp
## 1 01001 5.3
## 2 01003 5.4
## 3 01005 8.6
## 4 01007 6.6
## 5 01009 5.5
## 6 01011 7.2
Choropleth Map Using GeoJSON
library(plotly)
library(rjson)
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"
df <- read.csv(url2, colClasses=c(fips="character"))
g <- list(
scope = 'usa',
projection = list(type = 'albers usa'),
showlakes = TRUE,
lakecolor = toRGB('white')
)
fig <- plot_ly()
fig <- fig %>% add_trace(
type="choropleth",
geojson=counties,
locations=df$fips,
z=df$unemp,
colorscale="Viridis",
zmin=0,
zmax=12,
marker=list(line=list(
width=0)
)
)
fig <- fig %>% colorbar(title = "Unemployment Rate (%)")
fig <- fig %>% layout(
title = "2016 US Unemployment by County"
)
fig <- fig %>% layout(
geo = g
)
fig