How to display country flags on waffle chart symbols? (using, e.g,. `ggwaffle`)

187 Views Asked by At

I would like to create a waffle chart and use country flags in place of squares. Here is my current attempt using ggwaffle:

library(ggplot2)
library(emojifont)
library(ggwaffle)

iris2 <- iris
iris2$Species <- c("", "", "")

waffle_data <- waffle_iron(iris2, aes_d(group = Species))
waffle_data$label = fontawesome('fa-flag')

ggplot(waffle_data, aes(x, y, colour = group)) +
  geom_text(aes(label=label), family='fontawesome-webfont', size=7) +
  coord_equal() +
  scale_colour_waffle() +
  theme_waffle()

Created on 2023-06-18 with reprex v2.0.2

Is it possible at all with ggwaffle? I was also trying to play with ggflags but I don't see how to make these two compatible because ggflags replace points in a scatter plot.

I am also aware that Windows does not ship with country flag unicode emojis for political reasons, so base unicode wouldn't work (as in one of my previous attempts using the waffle package). So it would need to be a font that includes country flags or images thereof. Thanks for any help.

1

There are 1 best solutions below

9
Peter On BEST ANSWER

Using ggflags you could set the x and y coordinates to replicate a grid.

library(ggflags)
library(ggplot2)

df1 <- data.frame(x=rep(1:15, each = 10),
                  y=rep(1:10, 15),
                  country = c(rep("us", 75), rep("ca", 50), rep("gb", 25)))

ggplot(df1, aes(x, y, country=country)) + 
  geom_flag() +
  scale_country() +
  theme_void() +
  theme(legend.position = "bottom")

Created on 2023-06-18 with reprex v2.0.2

Here's a go at a function which can automate this, it's more than a bit hacky but may be useful as a starter...

library(ggflags)
library(ggplot2)



``` r
#' @param in_map_var string Vector of elements to be mapped to flags
#' @param len_x integer Length of x axis, number of flags on x axis
#' @param na_flag string ID of a flag which is nominally used for filling in the empty grid spaces, This is a hack.

waffle_map <- function(in_map_var, len_x = NA, na_flag = "ac"){

  # work out grid dimensions  
  var_count <- length(in_map_var)
  
  if(is.na(len_x)){
    x_count <- ceiling(sqrt(var_count))
  } else {
    x_count <- len_x
  }

  
  y_count <- ceiling(var_count / x_count)
  grid_count <- x_count * y_count
  
  df <- 
    data.frame(x = rep(1:y_count, each = x_count),
               y = rep(1:x_count, y_count),
               country = c(in_map_var, rep(na_flag, grid_count - var_count))
               )

  country_4legend <- unique(df$country)[unique(df$country) != na_flag]
  
  
  
  p <- 
    ggplot(df, aes(x, y, country = country)) + 
    geom_flag(size = 8) +
    scale_country(breaks = country_4legend) +
    theme_void() +
    theme(legend.position = "bottom")

    if(grid_count > var_count){
    p <- 
      p +
      geom_point(data = df[var_count:grid_count, ], aes(x, y), colour = "white", size = 10)
  }
                 
  return(p)
  
}

var_2map <- c(rep("us", 75), rep("ca", 50), rep("gb", 25))

waffle_map(var_2map, len_x = 15)


waffle_map(var_2map)

Created on 2023-06-18 with reprex v2.0.2