Fun with Flags (in R)


After three entries I thought it was time to show this blog to my sister. After reading (I don't believe you!) all three previous entries, she laconically said "reminds me of fun with flags". I'm not sure if she ment it as a compliment, but since I like "fun with flags", I took it as such. 

In any case, that was still better than my two nephews, who made no comment at all. Ignorance is the worst punishment? Although, between Apex Ledgends and Valorant there is really little time for such stupid things as programming.

After my sister's hint and the fact that I keep reading questions about geom_image and geom_bar in various forums, the topic today is ... Fun With Flags!

Lets visualize some macro economic data today. 

First question: Where do we get our data from? From the European Unions Spring 2020 Economic Forecast. We take a look at the debt to gdp ratios for selected countries.

We want to display the 2019 debt/GDP ratios in a bar chart and use a flag to show which bar belongs to which country.


Second question: Where do we get our flags from?

As we only want to show six countries we could copy those flags from wikipedia, but that is not a very sustainable solution. Easier might be downloading all country flags from flagpedia.net. There are two possibilities on their website. One with all flags having the same width and the other with all flags have the same heigth. Frankly, I dislike both. The reason is, if you put several flags close to each other (no matter which dimension) then unequal sizes look pretty disturbing.

What I want are equal width and equal height. This may be wrong from an offical point of view, and in some cases may look akward as well, but lets give it a try.

So I downloaded the flag set from flagpedia.org in width 320 and unzipped them into a directory. Now I  use Irfanview to bring them to the same dimensions. Irfanview is still an awesome program. I "bought" it (more a donation) approximately 25 years ago and the 100 austrian shillings I have spent were worth every penny (or Groschen). 
If you don't know how to change the size for all images in Irfanview, go to the directory in Windows Explorer, open one image in Irfanview and press the key "b". You are now in Batch conversion. Here you can convert all flags to the same resolution. As 320x213 is very common among the existing flags I use this resolution as target for all flags. If you need help with this ask in the comments below.

So lets start in R.

We need two libraries:

library(tidyverse)
library(ggimage)

To avoid confusions ggplot (part of tidyverse) is version 3.3.2, ggimage is version 0.2.8


First we determine the directory where R can find our new flags.
flagsdir = "C:/w320/"

Then we add
debt = tibble::tribble(
    ~Year,   ~IT,   ~ES,  ~FR,  ~DE,  ~AT,  ~NL,
  2011, 119.7,  69.9, 87.8, 79.8, 82.4, 61.7,
  2012, 126.5,  86.3, 90.6, 81.1, 81.9, 66.2,
  2013, 132.4,  95.8, 93.4, 78.7, 81.3, 67.7,
  2014, 135.4, 100.7, 94.9, 75.7,   84, 67.8,
  2015, 135.3,  99.3, 95.6, 72.1, 84.9, 64.6,
  2016, 134.8,  99.2,   98, 69.2, 82.9, 61.9,
  2017, 134.1,  98.6, 98.4, 65.3, 78.3, 56.9,
  2018, 134.8,  97.6, 98.4, 61.9,   74, 52.4,
  2019, 136.2,  96.7, 98.9, 59.2, 69.9, 48.9,
  2020, 136.8,  96.6, 98.9, 56.8, 67.2, 47.1
  )

At the moment we are only interested in the year 2019, as 2020 is only a forecast. And we want the order: the Netherlands, Germany, Austria, Spain, France and Italy. And we want tidy data!

debt_tidy = debt %>% 
  gather(key, value, -Year) %>% 
  filter(Year==2019) %>% 
  mutate(key = factor(key,
                      levels=c("NL","DE","AT","ES","FR","IT")),
         flags = paste0(flagsdir,key,".png"))

This may need some explanation:
gather in line two produces tidy data. One line for every year, for every country.
With determing the factors of key like this we can control the order in which the bars are displayed in the final graph.
The column flags holds the complete filename (name and directory) where R can find our flags. 

debt_tidy now looks like that:

# A tibble: 6 x 4
   Year key   value flags         
  <dbl> <fct> <dbl> <chr>         
1  2019 IT    136.  C:/w320/IT.png
2  2019 ES     96.7 C:/w320/ES.png
3  2019 FR     98.9 C:/w320/FR.png
4  2019 DE     59.2 C:/w320/DE.png
5  2019 AT     69.9 C:/w320/AT.png
6  2019 NL     48.9 C:/w320/NL.png

Finally:

ggplot(data=debt_tidy)+
  geom_bar(mapping = aes(x= key, 
                         y=value),
           fill= "darkgray",
           color = "black",
           stat = "identity",
           width = 0.7)+
  geom_image(mapping = aes(x= key, 
                           y=10, 
                           image=flags),
             size= .07, 
             asp= 1.35)+
  geom_text(mapping = aes(x= key, 
                          y=value,
                          label = round(value,0)),
            vjust=-1,
            size=5)+
  scale_y_continuous(sec.axis = dup_axis(),
                     limits = c(0,160),
                     labels = seq(0,150,50),
                     breaks = seq(0,150,50),
                     minor_breaks = seq(0,150,50))+
  labs(y="",
       x="",
       title= "Debt/GDP Ratio in %",
       caption = "Source: Terry Gamon (terrygamon.blogspot.com) , EU Commission")+
  theme_minimal()+
  theme(legend.position = "none")+
  theme(plot.title = element_text(size=22),
        plot.caption = element_text(size=12))+
  theme(panel.grid.major.x = element_blank()) +
  theme(axis.title.y.left = element_text(size=20, 
                                         angle = 0, 
                                         vjust=0.5),
        axis.title.y.right= element_text(size=20, 
                                         angle = 0, 
                                         vjust=0.5))+
  theme(axis.text.x = element_text(size=20),
        axis.text.y.left = element_text(size=17),
        axis.text.y.right= element_text(size=17))




I think the Code is pretty clear, but maybe a a word to this line: 

  geom_image(mapping = aes(x= key, 
                           y=10, 
                           image=flags),
             size= .07, asp=1.35)+


geom_image is from the library(ggimage). The syntax is simple, the aestetics contain x and y coordinates and the complete filename. Size and asp (aspect ratio) make it possible to determine the size and the aspect ratio of the image (thanks Captain Obvious). Frankly, I struggle to find out what measure the size has, for me the value comes from trial and error.

Just for the sake of completeness, you could also use geom_textured_col from the ggtextures package.
You can find it here:

devtools::install_github("clauswilke/ggtextures")
library(ggtextures)

Skip the geom_bar and geom_image lines above and add:

  geom_textured_col(mapping = aes(x = key, 
                                  y=value, 
                                  image=flags),
                    width = 0.7)+

 And you will get: 


I personally don't like it, but maybe it fits your taste.


Now we want to show how the debt to GDP ratios changed during the years for all countries in our sample.

First we remove the constriction of the year:

debt_tidy = debt %>% 
  gather(key, value, -Year) %>% 
  mutate(key = factor(key,
                      levels=c("NL","DE","AT","ES","FR","IT")),
         flags = paste0(flagsdir,key,".png"))

but we need the last year (2020) seperately.

last = debt_tidy %>% 
  filter(Year == 2020)

we also want to change the x-axis labels

Years = debt %>% 
  select(Year) %>% 
  mutate(Year = substr(Year,2,5)) %>% 
  mutate(Year= as.numeric(Year)) %>% 
  unlist(use.names = F) 

Finally:

ggplot() + 
  geom_bar(data= debt_tidy,
           aes(x=Year, 
               y=value, 
               fill= key),
           stat="identity", 
           position="dodge", 
           width=0.7, 
           alpha=0.2)+
  geom_line(data= debt_tidy,
            aes(x=Year, 
                y=value), 
            size=2)+
  geom_point(data= debt_tidy,
             aes(x=Year, 
                 y=value), 
             size=3)+
  geom_text(data=last, 
            aes(x=Year, 
                y= value+7, 
                label=paste0(round(value,0)," %")),
            hjust=.7)+
  geom_image(data = last,
             aes(x=2015.5, 
                 y= 150, 
                 group= key, 
                 image= flags),
             size=0.25, asp=.4)+
  scale_y_continuous(limits = c(0,150),
                     labels= seq(0,150,25),
                     breaks = seq(0,150,25),
                     minor_breaks = seq(0,150,25))+
  scale_x_continuous(labels = Years,
                     breaks = seq(2011,2020,1),
                     minor_breaks = seq(11,20,1)) +
  scale_fill_manual(values = palette_rcm())+
  facet_grid(. ~ key)+
  geom_hline(yintercept = 60)+
  theme_minimal()+
  labs(title="Debt/GDP in %",
       subtitle = "",
       y="",
       x="",
       caption = "Source: Terry Gamon (terrygamon.blogspot.com) , EU Commission")+
  theme(legend.title = element_blank(), 
        legend.position = "none",
        legend.text=element_text(size=20))+
  theme(axis.text.x=element_text(size=10,angle = 0, vjust =.5),
        axis.title.x=element_text(size=20)) +
  theme(axis.text.y=element_text(size=20),
        axis.title.y=element_text(size=20))+
  theme(axis.ticks = element_line(),
        axis.ticks.length = unit(5, "pt"))+
  theme(strip.text.x = element_text(size = 22, color="blue"))+
  theme(panel.grid.major.x = element_blank()) +
  theme(
    plot.title = element_text(size=25),
    plot.caption = element_text(size=12))+
  list()




Thanks! Have Fun with your ggplot Flags!












 

Comments

Popular posts from this blog

Breaking Excel Encryption (Password Recovery) Part 1

Ultima 5 Underworld in R

Schach mit ggplot