library(mxmaps)

data("df_mxstate_2020")
df_mxstate_2020$value <- df_mxstate_2020$pop
mxstate_choropleth(df_mxstate_2020,
                    title = "Total population, by state") 

Change the color scale

library(mxmaps)
library(viridis)
library(scales)

df_mxstate_2020$value <-  df_mxstate_2020$indigenous_language / 
  df_mxstate_2020$pop 
gg = MXStateChoropleth$new(df_mxstate_2020)
gg$title <- "Percentage of the population that speaks\nan indigenous language"
gg$set_num_colors(1)
gg$ggplot_scale <- scale_fill_viridis("percent", labels = percent)
gg$render()

Map with labels for each state

library("geojsonio")
library("ggplot2")
library("ggrepel")
library("sf")
library("RJSONIO")

df_mxstate_2020$value <-  df_mxstate_2020$indigenous_language / 
  df_mxstate_2020$pop * 100
p <- mxstate_choropleth(df_mxstate_2020, 
                        num_colors = 1,
                        title = "Percentage of the population that speaks\nan indigenous language",
                        legend = "%")


data("mxstate.topoJSON")

tmpdir <- tempdir()
# have to use RJSONIO or else the topojson isn't valid
write(RJSONIO::toJSON(mxstate.topoJSON), file.path(tmpdir, "state.topojson"))
states <- topojson_read(file.path(tmpdir, "state.topojson"))

# make sure the coordinates of the labels are in the correct order
 
df_mxstate_2020$lon <- st_coordinates(st_centroid(states))[,1]
df_mxstate_2020$lat <- st_coordinates(st_centroid(states))[,2]


df_mxstate_2020$group <- df_mxstate_2020$state_abbr

p +
  geom_text_repel(data = df_mxstate_2020, 
                  aes(lon, lat, label = state_abbr,), 
                  size = 3,
                  box.padding = unit(0.1, 'lines'), 
                  force = 0.1)

Legends

Add a legend for states with NA values

df_na <- df_mxstate_2020
df_na$value[1:20] <- NA
mxstate_choropleth(df_na,
                   num_colors = 1,
                   title = "Percentage of the population that speaks\nan indigenous language",
                   legend = "%") +
  # Add a fake color scale which we'll change to 'no data'
  geom_point(data = df_mxmunicipio_2020[1,],
             size = -1,
             aes(color = "",
                 group = NA)) +
  scale_color_manual(values = NA) +
  scale_fill_continuous(low="orange", high="darkred", 
                        na.value = "lightgray") +
  theme(legend.key = element_rect(color = "black")) + # Add a border to the legend
  # Add an extra color legend with a giant square
  guides(color = guide_legend("no data",
                              override.aes=list(color = "lightgray",
                                                shape = 15, # shape 15 is a black square
                                                size = 7)))

facet_grid like functionality

Currently mxmaps is not compatible with facet_grid, but we can mimic the same functionality by using the function ggarrange from the ggpubr package

library(mxmaps)
library(ggplot2)
library(ggpubr)

data("df_mxstate_2020")
df <- rbind(df_mxstate_2020, df_mxstate_2020)

df$genero <- rep(c("m", "f"), each= 32)
df$value <- ifelse(df$genero == "m", df$pop_male, df$pop_female)
# This is needed so that both the male and female population scales have
# the same values
df$value <- cut(df$value, breaks = c(0, 5e4, 1e6, 2e6, 4e6, 20e7))


f <- mxstate_choropleth(subset(df, genero == "f"),
                        title = "F population, by state",
                        num_colors = 5) 
m <- mxstate_choropleth(subset(df, genero == "m"),
                        title = "M population, by state",
                        num_colors = 5)

ggarrange(f, m,
          labels = c("", ""),
          ncol = 1, nrow = 2)