Home > Back-end >  Bubble chart with round country flag symbols in ggplot/ggimage
Bubble chart with round country flag symbols in ggplot/ggimage

Time:03-29

I try to make a bubble chart with ggplot/ggimage by including the country flag. Here is a reproducible example:

library(dplyr)
library(ggplot)
library(ggimage)

A <- data.frame(X = c(1,4,5), Y = c(10, 1, 5), Z = c(1, 2, 3)/30, Country = c("FR", "BE", "IT"), CountryFlag = paste0("https://flagcdn.com/h20/", str_to_lower(Country), ".png"))

A_plot <- ggplot(A, mapping = aes(x = X, y = Y, size = I(Z), image = CountryFlag))  
          geom_image()

X11(); print(A_plot)

Except downloading the rounded flags, is that possible to transform the flag as rounded or is it possible to insert the country in a bubble. I tried the following code but it doesn't work:

library(dplyr)
library(ggplot)
library(ggimage)

A <- data.frame(X = c(1,4,5), Y = c(10, 1, 5), Z = c(1, 2, 3), Country = c("FR", "BE", "IT"), CountryFlag = paste0("https://flagcdn.com/h20/", str_to_lower(Country), ".png"))

A_plot <- ggplot(A, mapping = aes(x = X, y = Y, size = Z, image = CountryFlag))  
          geom_point(alpha = 0.5, col = "lightblue")  
          geom_image()

X11(); print(A_plot)

I get the error:

Error in `[<-`(`*tmp*`, !is.na(alpha), 4, value = alpha[!is.na(alpha)]) : 
  (subscript) logical subscript too long
In addition: Warning message:
In rep(colour, length.out = length(alpha)) :
  'x' is NULL so the result will be NULL

Any suggestion is welcome.

CodePudding user response:

Here's a function that adds a circular mask to each flag. If we start with your plot,

A_plot

enter image description here

We get the urls and create some local filenames:

flags <- A_plot$data$CountryFlag
png_files <- sapply(strsplit(flags, "/"), function(x) x[length(x)])

Now we create some images with a circular mask and save them locally:

OK <- Map(function(flag, png) {
  im <- magick::image_read(flag)
  im <- magick::image_resize(im, magick::geometry_size_percent(500, 2000))
  ii <- magick::image_info(im)
  width <- ii$width
  fig <- magick::image_draw(magick::image_blank(height, height))
  symbols(width/2, width/2, circles=(width/2), bg='black', inches=FALSE, add=TRUE)
  im2 <- magick::image_composite(im, fig, operator='copyopacity')
  magick::image_write(im2, png)
}, flag = flags, png = png_files)

Now write these file paths as our image locations in the plot object:

A_plot$data$CountryFlag <- png_files

Which changes our plot to:

A_plot

enter image description here

For completeness, we should tidy up after ourselves once the plot is drawn:

sapply(png_files, unlink)
  • Related