How do I count thee? Let me count the ways?

Sheldon Cooper's favorite number

      If you are a fan of the television series "The Big Bang Theory", then you know Sheldon often wears a shirt with 73 ...

Showing posts with label map. Show all posts
Showing posts with label map. Show all posts

Sunday, June 23, 2024

Something a llttle different: Hexbin maps

Something a llttle different: Hexbin maps by Jerry Tuttle

      I recently became acquainted with hexbin maps, so I thought I would experiment with one. In a hexbin map, each geographical region is represented by an equally sized regular hexagon. (A regular hexagon can tessellate a plane, one of only three regular polygons that can do so besides an equilateral triangle and a square.) A hexbin map can be used to illustrate the distribution of a categorical variable by using colors, at a cost that geographical areas are distorted by size, shape, and orientation. Here is a hexbin map, followed by the same data in a conventional map. The four categories represent which of the two political parties had the larger popular vote in the 2020 presidential election and by what margin over the other party.

# Hexbin map

# Conventional map
      A hexbin is based on a geoJson file that provides the hexagon boundaries as two-dimensional coordinates. I downloaded a file from https://team.carto.com/u/andrew/tables/andrew.us_states_hexgrid/public/map in geo json format containing the boundaries of the US states. I read it in with read_sf from the R sf (simple features spatial vector data) library. I used a datafile of 2020 presidential election popular votes by state scraped from https://www.presidency.ucsb.edu/statistics/elections/2020 . I binned percent Democraric votes to total votes minus percent Republican votes to total votes into four bins and joined to the sf file. I used ggplot to plot the hexbin map, where label = iso3166_2 provides a two-character state abbreviation.

      For the conventional map, I used the R usmap library.

      A hexbin map is a nice alternative to a conventional map. With a conventional map, it's hard to read those small states. Howwever, it is not the right visualization tool if the data is quantitative. It is also not the right tool if the size or geography is important. Utah is not the same size as Califirnia in either area or number of voters, and South Carolina is not east of North Carolina.

      An alternative to hexagonal areas is to make them squares, but hexagons seem more interesting.

      Here is the R code I used:

# plot the conventional map first:
library(usmap)
# Color maps with data; must have fips column
library(ggplot2)
library(readxl)
data <- read_excel("C:/Users/Jerry/Desktop/R_files/presidential_2020.xlsx")
data$party <- ifelse(data$Dem_Minus_Rep >=0 & data$Dem_Minus_Rep <= 0.10, 'Dem 0 to 10%',
      ifelse(data$Dem_Minus_Rep > 0.10, 'Dem > 10%',
      ifelse(data$Dem_Minus_Rep <0 & data$Dem_Minus_Rep >= -0.10, 'Rep 0 to 10%',
      ifelse(data$Dem_Minus_Rep < -0.10, 'Rep > 10%', "Error"))))
#
party_colors <- c("blue", "lightskyblue", "red", "#FF66CC")
mytitle="2020 Presidential Election Popular Vote by State"
#
plot_usmap(data = data, values = "party", labels = TRUE, label_color = "white") +
    labs(title=mytitle) +
    scale_fill_manual(values=party_colors) +
    theme(
      legend.position="bottom",
      plot.title = element_text(size=15, face="bold"),
      legend.title = element_text(size=12, face="bold"),
      legend.text = element_text(size=12, face="bold"))
#
# plot the hexbin map:
# Download coordinates from https://team.carto.com/u/andrew/tables/andrew.us_states_hexgrid/public/map
# in geo json format
my_sf <- read_sf("C:/Users/Jerry/Desktop/R_files/us_states_hexgrid.geojson")
my_sf <- my_sf %>%
    mutate(google_name = gsub(" \\(United States\\)", "", google_name))
#
# join sf file with data file
my_sf_data <- my_sf %>%
    left_join(data, by = c("google_name" = "STATE"))
#
ggplot(my_sf_data) +
    geom_sf(aes(fill = party), linewidth = 0, alpha = 0.9) +
    geom_sf_text(aes(label = iso3166_2), color = "white", size = 4, alpha = 1) +
    theme_void() +
    scale_fill_manual(values=party_colors) +
    ggtitle(mytitle) +
    theme(
      legend.position="bottom",
      plot.title = element_text(size=15, face="bold"),
      legend.title = element_text(size=12, face="bold"),
      legend.text = element_text(size=12, face="bold"))
# End

##################################################################################