Choropleth map (incl. automated search)

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Example was tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.2.0.

See method of constructing choropleth map - with ggplot2 and sf - based on a shape file. Example is presented on World Development Indicator - Population Ages 65 & Above data from World Bank. Jump to the code.

Map created with ggplot2 and sf packages. Search query is based on concept metadata. You only need code for one series and the rest is downloaded automatically. To see not-based-on-search method see Circular bar chart method.

Based on a shape file, with 'search by concept', ggplot2 + sf packages

library(MacrobondAPI)
library(tidyverse)
library(countrycode)
library(sf) #for map's shape
library(broom)
library(viridis) #for colors

###DATA PART
#choose series
series<-FetchOneTimeSeries("af_sp_pop_65up_to_zs")
#get the concept of a series and create search query based on it
query <- CreateSearchQuery() 
setEntityTypeFilter(query, "TimeSeries") 
addAttributeValueFilter(query, "RegionKey", getConcepts(series)) 
country_set <- getEntities(SearchEntities(query))

#create empty vectors
list_of_series<-NULL
values<-NULL
ISO2<-NULL
country<-NULL

#get list of series' codes
for (i in country_set){
  list_of_series<-append(list_of_series, getName(i))
}

#get last values 
for (i in list_of_series){
  values<-append(values, last(getValues(FetchOneTimeSeries(i))))
}

#get countries ISO codes
for (i in list_of_series){
  ISO2<-append(ISO2, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}

#change ISO codes to country names
country<-countrycode(as.vector(ISO2), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(values, ISO2, country) %>%
  drop_na() %>%
  mutate(ISO2=str_to_upper(ISO2)) #shape file has ISO codes in upper cases


###MAP INFO PART (based on a shape file)
#This example uses shape file from: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip

#Read shape file with the sf library. You'll get a data frame.
map <- st_read("C:/Users/name.name/Desktop/R/DATA", 
layer="TM_WORLD_BORDERS_SIMPL-0.3")

###DATA + MAP
#join map info and data
map_final <- full_join(map , data, by="ISO2")

#plot
ggplot() +
  geom_sf(data = map_final, colour = "black", size = 0.2, aes(fill = values)) +
  theme_void()+
  ggtitle("Percentage of population ages 65 and above")+
  scale_fill_viridis(option="D", direction=-1, #color scale's & legend's settings
                     breaks=c(5,10,15,20,25,30,35), 
                     name=" %")+
  theme(plot.title=element_text(size=rel(1.5), hjust=0.5), #additional settings for title and legend
        legend.position=c(0.15, 0.35))

Radar chart

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.3.0.

See two methods of constructing radar charts - with ggplot2 + ggradar and fsmb. Examples are presented on Innovation Input Sub-index from Global Innovation Index.

 

Radar chart version 1 created with ggplot2 and ggradar packages (click to enlarge). Jump to code with ggplot2 + ggradar package.

 

 

 


Radar chart version 2 with fmsb package (click to enlarge). Jump to code with fmsb package.

 

With ggplot2 + ggradar

library(MacrobondAPI)
library(tidyverse)
library(countrycode)
library(ggradar)

#First column is the name of the groups and each column represents a variable.
#All columns must have the same scale.
#If the values of your columns are not between 0 and 1 you will need to specify the minimum value with grid.min and the maximum value with grid.max.

#create list of series
list_of_series<-c("gii0828", "gii0974", "gii1266", "gii0682", "gii1120", #Nigeria
                  "gii0849", "gii0995", "gii1287", "gii0703", "gii1141", #South Africa
                  "gii0773", "gii0919", "gii1211", "gii0627", "gii1065") #Ethiopia

#create empty vectors
values<-NULL
region<-NULL

#get region
for (i in list_of_series){
  region<-append(region, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}
#change region ISO codes to names
region<-countrycode(as.vector(region), origin="iso2c", destination ="country.name")

#set description
description_labels<-c("Human Capital & Research", "Infrastructure", "Business \nSophistication", 
                      "Institutions", "Market \nSophistication")
descriptions<-rep(description_labels, 3) #create this for data frame

#get values 
for (i in list_of_series){
  values<-append(values, last(getValues(FetchOneTimeSeries(i))))
}

#prepare data frame
data <- data.frame(region, descriptions, values)
#change format of data from long to wide
data <- spread(data, descriptions, values)

#set colors
colors <- c("#58A291", "#F68D2E", "#CD545B")

#plot
ggradar(data, 
        values.radar = c(0, 40, 80), #0%, 50%, 100% of values
        axis.labels = c(description_labels), #description of each 'arm'
        grid.min=0,grid.mid=40, grid.max=80, #grid labels
        background.circle.colour = "white", #background settings
        axis.line.colour = "grey", #axis line's settings
        axis.label.size=4,
        gridline.min.colour = "grey", #gridlines' settings
        gridline.mid.colour = "grey",
        gridline.max.colour = "grey",
        grid.label.size=5,
        group.colours = colors, #chart's lines settings
        group.line.width= 1.2,
        group.point.size=5,
        legend.title="Global Innovation Index", #legend's settings
        legend.position = "top", 
        legend.text.size = 10)

With fmsb

library(MacrobondAPI)
library(tidyverse)
library(countrycode)
library(fmsb)

#create list of series
list_of_series<-c("gii0828", "gii0974", "gii1266", "gii0682", "gii1120", #Nigeria
                  "gii0849", "gii0995", "gii1287", "gii0703", "gii1141", #South Africa
                  "gii0773", "gii0919", "gii1211", "gii0627", "gii1065") #Ethiopia

#create empty vectors
values<-NULL
region<-NULL

#get region
for (i in list_of_series){
  region<-append(region, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}
#change ISO codes to names
region<-countrycode(as.vector(region), origin="iso2c", destination ="country.name")

#set description
description_labels<-c("Human Capital & Research", "Infrastructure", "Business \nSophistication", 
                      "Institutions", "Market \nSophistication")
descriptions<-rep(description_labels, 3) #create this for data frame

#get values 
for (i in list_of_series){
  values<-append(values, last(getValues(FetchOneTimeSeries(i))))
}

#Data frame must have first row representing the maximum values of the data and the second row the minimum values.
#prepare data frame
data <- data.frame(region, descriptions, values)
#prepare data frame for max and min values
max_min <- as.data.frame(rbind(rep(80, 5), rep(0, 5)))
rownames(max_min) <- c("max", "min")
colnames(max_min) <- description_labels
                      
#change format of data from long to wide
data <- spread(data, descriptions, values) %>%
  column_to_rownames(var="region") #move first column to row names
data <- rbind(max_min, data) #join two data frames

#set colors
colors <- c("#58A291", "#F68D2E", "#CD545B")

#plot (mark radar chart and legend to plot them together)
radarchart(data, 
           axistype=1, #gridlines' settings
           cglcol = "gray", 
           axislabcol="grey", 
           caxislabels=c(0,20, 40, 60, 80), 
           pcol = colors, #chart's lines settings
           plty = 1,
           plwd = 2,
           vlcex=0.8, #size of value labels
           title = "Global Innovation Index") 

legend(x=1.3, y=1, #legend's position
       legend = rownames(data[-c(1,2),]), #exclude names for max and min
       bty="n", #border around legend, n=none
       pt.cex=1.8, #width of sample colors
       pch = 20,
       col = colors)

Ridgeline

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.3.0.

See below how to construct ridgeline chart with packages ggplot2 + ggridge. Example is presented on Australia's temperature data from Australian Bureau of Meteorology. Jump to the code.

 

 

 

 

 

Images from code for plot 1 (ridges2), plot 2 (ridges_gradient).

With ggplot2 + ggridges packages

library(MacrobondAPI)
library(ggplot2)
library(ggridges)
library(tidyverse)

#select series
series<-c("auenvo0013")

#get dates
dates<-getDatesAtStartOfPeriod(FetchOneTimeSeries(series))

#get values
values<-getValues(FetchOneTimeSeries(series))

#create data frame for plot 1 (two categories)
data<-data.frame(dates, values) %>%
  mutate(year=as.character(lubridate::year(dates)), #create column with year
         quarter=as.character(lubridate::quarter(dates))) %>% #create column with quarter
  mutate(quarter = fct_relevel(quarter, levels = "4", "3", "2", "1")) %>% #to have specific order of data in ggplot2 you need to set levels
  filter(year %in% c(1871, 2021)) #filter data for specific periods

#create data frame for plot 2 (one category)
data2<-data.frame(dates, values) %>%
  mutate(year=as.character(lubridate::year(dates)), #create column with year
         quarter=as.character(lubridate::quarter(dates))) %>% #create column with quarter
  mutate(quarter = fct_relevel(quarter, levels = "4", "3", "2", "1")) %>% #to have specific order of data in ggplot2 you need to set levels
  filter(year %in% c(2021)) #filter data for specific period

#plot 1, with transparent colors
ggplot(data, aes(x = values, y =quarter, fill=year)) +
  geom_density_ridges2(alpha = 0.7, #ggridges option
                       scale=1) + 
  scale_fill_manual(values=c("#ffd700", "#cc2d0c")) + #colors
  scale_x_continuous(breaks=c(-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45)) + #set specific ticks on x-axis
  xlab("high air temperature") + #x-axis label
  ylab("quarter of year") + #y-axis label
  ggtitle("Australia, Sydney") + #title
  theme_minimal()

#plot 2, with cold-hot gradient
ggplot(data2, aes(x = values, y =quarter, fill=stat(x))) +
  geom_density_ridges_gradient(scale=1, #ggridges option
                               linetype=0)+ #border lines
  scale_fill_viridis_c(name = "Temp.", option = "C")+ #colors + legend's title
  scale_x_continuous(breaks=c(-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45)) + #set specific ticks on x-axis
  xlab("high air temperature") + #x-axis label
  ylab("quarter of year") + #y-axis label
  ggtitle("Australia, Sydney 2021") + #title
  theme_minimal()

Streamchart (uneven data)

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.3.0.

See below how to construct streamchart with packages ggplot2 + ggstream. Example is presented on China's electricity generation data from China National Bureau of Statistics (NBS). Jump to the code.

Images from code for plot 1, plot 2 (proportional type) and plot 3 (ridge type).

With ggplot2 + ggstream packages

library(MacrobondAPI)
library(tidyverse)
library(ggstream)

#create list of series from Macrobond database
list_of_series<-c("cnprod0168", "cnprod0169", "cnprod0272", "cnprod0291", "cnprod0816")
#note, series in this example have uneven history 

#create empty vectors
dates<-NULL
descriptions_short<-NULL
values<-NULL

#get dates
for (i in list_of_series){
  dates<-append(dates, getDatesAtStartOfPeriod(FetchOneTimeSeries(i)))
}

#get names
#to get the neat description AND right number of descriptions for data frame you need additional steps:
#1.download series description metadata with MacrobondAPI
#2.remove unwanted string from it with str_remove
#3.download all dates from that series with MacrobondAPI and calculate length of such vector
#4.use the number in rep(x, length)
#append(reproduce(shorten_it(name), length(number of dates)))
for (i in list_of_series){
  descriptions_short<-append(descriptions_short, rep(str_remove(getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Description"), "Electricity Generation, "),length(getDatesAtStartOfPeriod(FetchOneTimeSeries(i)))))
}

#get values 
for (i in list_of_series){
  values<-append(values, getValues(FetchOneTimeSeries(i)))
}

#create data frame
data <- data.frame(year=dates, name=descriptions_short, value=values) %>%
  mutate(value=na.approx(value)) %>% #fill NA with interpolated values
  mutate(name=factor(name, levels=c("Solar Power","Wind Power", "Nuclear Power", "Hydro Power","Thermal Power"))) #for ggplot2 you need to select order of factor levels, otherwise it will be alphabetical

#colors
colors <- c("#f8d623", "#d5f0f0", "#a80092", "#43a2e2","#1c0606")

#plot 1
ggplot(data, aes(x = year, y = value, fill = name)) +
  geom_stream()+ 
  scale_fill_manual(values = colors)+ #colors
  theme_minimal()+ #theme
  guides(fill=guide_legend(title="China's Energy Mix"))+ #legend's title
  xlim(limits = as.Date(c("1990-01-01", NA))) #shorten x-axis

#plot 2
ggplot(data, aes(x = year, y = value, fill = name)) +
  geom_stream(type = "proportional")+ #type of streamchart
  scale_fill_manual(values = colors)+ #colors
  theme_minimal()+ #theme
  guides(fill=guide_legend(title="China's Energy Mix"))+ #legend's title
  xlim(limits = as.Date(c("1990-01-01", NA))) #shorten x-axis

#plot 3
ggplot(data, aes(x = year, y = value, fill = name)) +
geom_stream(type = "ridge")+ #type of streamchart
scale_fill_manual(values = colors)+ #colors
theme_minimal()+ #theme
guides(fill=guide_legend(title="China's Energy Mix"))+ #legend's title
xlim(limits = as.Date(c("1990-01-01", NA))) #shorten x-axis

Slope chart (incl. vintage/revision data)

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.3.0.

See two methods of constructing slope charts - with CGPfunctions and ggplot2. Example is presented on IMF’s annual CPI data. Below them you will find example using vintage data (revision history) on DG ECFIN's CPI estimate data.

 

Slope chart version 1 created with CGPfunctions package (click to enlarge). Jump to the code with CGPfunctions.

 

 

 

 

Slope chart version 2 created with ggplot2 + ggrepel packages (click to enlarge). Jump to the code with ggplot2.

 

 

 

 

Slope chart version 3 created with CGPfunctions package (click to enlarge). It uses vintage (revision history) data. Jump to the code.

 

With CGPfunctions package

library(MacrobondAPI)
library(countrycode)
library(tidyverse)
library(CGPfunctions)

#download series
list_of_series <- c("imfcpi_132a_pcpiha_ix", "imfcpi_134a_pcpiha_ix", "imfcpi_136a_pcpiha_ix", "imfcpi_935a_pcpiha_ix", "imfcpi_936a_pcpiha_ix", "imfcpi_944a_pcpiha_ix", "imfcpi_964a_pcpiha_ix", "imfcpi_968a_pcpiha_ix")

#create empty vectors
values_1<-NULL
values_2<-NULL
country<-NULL

#get first values from a specific date
for (i in list_of_series){
  values_1<-append(values_1, getValueAtDate(FetchOneTimeSeries(i), as.Date("2019-01-01")))
}

#get second values 
for (i in list_of_series){
  values_2<-append(values_2, last(getValues(FetchOneTimeSeries(i))))
}

#get country name
for (i in list_of_series){
  country<-append(country, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}
#change ISO codes to names
country<-countrycode(as.vector(country), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(values_1, values_2, country) 
colnames(data) <- c("Year2019","Year2021","country") #set column names specific for this data set
data <- mutate(data, Year2019=round(Year2019, 1), Year2021=round(Year2021, 1)) #round up values 
data <- gather(data, key="year", value="value", Year2019:Year2021) #restructure data for the slope graph

#prepare colors
colors <- c("Hungary" = "#F68D2E", "Czechia" = "gray",
          "Romania" = "gray", "Slovakia" = "gray",
          "Germany" = "gray", "France" ="gray",
          "Poland"="#CD545B", "Euro Area" = "blue", 
          "Italy" = "gray")

#chart
newggslopegraph(dataframe = data,
                Times = year,
                Measurement = value,
                Grouping = country,
                Title = "Consumer Price Index",
                SubTitle = "Harmonized, All Items",
                Caption = "Source: IMF",
                LineThickness = 1.5,
                LineColor = colors,
                XTextSize = 8, #size of the column title
                YTextSize = 3.2, #size of the country name
                DataTextSize = 4.2, #size of the value
                TitleTextSize = 17,
                SubTitleTextSize = 10,
                CaptionTextSize = 8)

With ggplot2 + ggrepel packages

library(MacrobondAPI)
library(countrycode)
library(tidyverse)
library(ggplot2)
library(ggrepel)

#download series
list_of_series <- c("imfcpi_132a_pcpiha_ix", "imfcpi_134a_pcpiha_ix", "imfcpi_136a_pcpiha_ix", "imfcpi_935a_pcpiha_ix","imfcpi_936a_pcpiha_ix", "imfcpi_944a_pcpiha_ix", "imfcpi_964a_pcpiha_ix", "imfcpi_968a_pcpiha_ix")

#create empty vectors
values_1<-NULL
values_2<-NULL
country<-NULL

#get first values from a specific date
for (i in list_of_series){
  values_1<-append(values_1, getValueAtDate(FetchOneTimeSeries(i), as.Date("2019-01-01")))
}

#get second values 
for (i in list_of_series){
  values_2<-append(values_2, last(getValues(FetchOneTimeSeries(i))))
}

#get country name
for (i in list_of_series){
  country<-append(country, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}
#change ISO codes to names
country<-countrycode(as.vector(country), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(values_1, values_2, country)
colnames(data) <- c("Year2019","Year2021","country") #set column names specific for this data set
data <- mutate(data, Year2019=round(Year2019, 1), Year2021=round(Year2021, 1)) #round up values 
data <- gather(data, key="year", value="value", Year2019:Year2021) 

#chart 
ggplot(data = data, aes(x = year, y = value, group = country)) + 
geom_line(aes(color = country, alpha = 1), size = 1) + 
geom_point(aes(color = country, alpha = 1), size = 3) + 
geom_text_repel(data = data %>% filter(year == "Year2019"), #filter data to apply settings only to the left group
            aes(label=paste0(country, " - ", value)),
            hjust = 1.4, size=2.5, fontface = "bold")+
  geom_text_repel(data = data %>% filter(year == "Year2021"), #filter data to apply settings only to the right group
            aes(label=paste0(value, " - ", country)),
            hjust = -0.4, size=2.5, fontface = "bold")+
  labs(title = "Consumer Price Index",
       subtitle = "Harmonized, All Items",
       caption = "Source: IMF")+
  theme(legend.position = "none", #cleaning graphic elements
        panel.border = element_blank(),
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        axis.title.x = element_blank(),
        panel.grid.major.x = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size=14, face = "bold"),
        plot.subtitle = element_text(size=8),
        plot.caption = element_text(size=8))+
  scale_x_discrete(position = "top")

With vintage data (revision history)

library(MacrobondAPI)
library(countrycode)
library(tidyverse)
library(CGPfunctions)

#download series
list_of_series <- c("ameco_bgr_1_0_0_0_zcpih", "ameco_hun_1_0_0_0_zcpih","ameco_pol_1_0_0_0_zcpih", "ameco_rom_1_0_0_0_zcpih")

#create empty vectors
values_1<-NULL
values_2<-NULL
country<-NULL

#check vintage times, when series was updated?
getVintageTimes(FetchOneTimeSeriesWithRevisions("ameco_deu_1_0_0_0_zcpih"))

#get value from vintage series for specified date
for (i in list_of_series){
  values_1<-append(values_1, last(getValues(getVintage(FetchOneTimeSeriesWithRevisions(i), as.Date("2021-12-01")))))
}

#get last value from current series 
for (i in list_of_series){
  values_2<-append(values_2, last(getValues(FetchOneTimeSeries(i))))
}

#get country name
for (i in list_of_series){
  country<-append(country, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}
#change ISO codes to names
country<-countrycode(as.vector(country), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(round(values_1, 1), round(values_2, 1), country) #round up series in one move
colnames(data) <- c("2021 q4","2022 q1","country") #set column names specific for this data set
data <- gather(data, key="year", value="value", "2021 q4":"2022 q1") #restructure data for the slope graph

#prepare colors
colors <- c("Bulgaria" = "#F68D2E","Hungary" = "gray", 
            "Poland" = "#CD545B", "Romania"="gray")

#chart
newggslopegraph(dataframe = data,
                Times = year,
                Measurement = value,
                Grouping = country,
                Title = "CPI, estimate for 2023",
                SubTitle = "From 2021 Q4 and 2022 Q2",
                Caption = "Source: DG ECFIN",
                LineThickness = 1.5,
                LineColor = colors,
                XTextSize = 7, #size of the column title
                YTextSize = 3.2, #size of the country name
                DataTextSize = 4.2, #size of the value
                TitleTextSize = 17,
                SubTitleTextSize = 10,
                CaptionTextSize = 8)

Circular bar chart (incl. automated search)

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.4.0.

The first method uses 'search by concept' to find whole data set based on one series. Example is presented on Annual Hours Worked per Worker data from Conference Board TED.

 

Circular Bar chart method 1 created with ggplot2 package (click to enlarge). Search query is based on concept metadata. You only need code for one series and the rest is downloaded automatically. Jump to the code.

Circular Bar chart method 2 created with ggplot2 package. In this example codes are loaded manually. Jump to the code.

With 'search by concept'

library(MacrobondAPI)
library(ggplot2)
library(tidyverse)
library(countrycode)

#choose series
series<-FetchOneTimeSeries("ted_ar_ahw")
#get the concept of a series and create search query based on it
query <- CreateSearchQuery() 
setEntityTypeFilter(query, "TimeSeries") 
addAttributeValueFilter(query, "RegionKey", getConcepts(series)) 
country_set <- getEntities(SearchEntities(query))

#create empty vectors
list_of_series<-NULL
values<-NULL
country<-NULL

#get list of series' codes
for (i in country_set){
  list_of_series<-append(list_of_series, getName(i))
}

#get last values 
for (i in list_of_series){
  values<-append(values, last(getValues(FetchOneTimeSeries(i))))
}

#get export countries ISO codes
for (i in list_of_series){
  country<-append(country, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}

#change ISO codes to names
country<-countrycode(as.vector(country), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(values, country) %>%
  drop_na() %>% #remove NA, useful when data set has series for group of countries
  arrange(values) %>% #this will sort data frame only
  mutate(country=factor(country, levels=country)) #for ggplot2 you need to plot factor levels too
data <- mutate(data, id=seq(from=1, to=nrow(data)))

#prepare labels data
label_data <- data

#calculate the ANGLE of the labels
number_of_bar <- nrow(label_data)
#subtract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
angle <-  90 - 360 * (label_data$id-0.5) /number_of_bar 

#calculate the alignment of labels: right or left
label_data$hjust<-ifelse(angle < -90, 1, 0)
#flip angle 'by' to make them readable
label_data$angle<-ifelse(angle < -90, angle+180, angle)

#chart
p <- ggplot(label_data, aes(x=country, y=values)) + 
  geom_bar(stat="identity", fill=alpha("#9054a5",1)) + #select color
  ylim(-800,3000)+
  coord_polar(start = 0)+
  theme_minimal() +
  theme(
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  )+
  geom_text(data=label_data, aes(x=id, y=values+5, label=country, hjust=hjust), 
            color="black", family="Helvetica", fontface="bold",alpha=1, size=1.7, angle= label_data$angle, inherit.aes = FALSE)+ #add country labels
  geom_text(data=label_data, aes(x=id, y=(-100), label=round(values,0), hjust=hjust), 
            color="black", family="Helvetica",alpha=1, size=1, angle=label_data$angle, inherit.aes = FALSE) #add value labels

#add title
p + ggtitle("Annual Hours Worked per Worker")+
  theme(plot.title = element_text(face="bold", size=12, hjust = 0.5))

With manual download

library(MacrobondAPI)
library(ggplot2)
library(tidyverse)
library(countrycode)

#add series
list_of_series<-c("ted_ar_ahw", "ted_au_ahw", "ted_at_ahw", "ted_bd_ahw", "ted_be_ahw", "ted_br_ahw", "ted_bg_ahw", "ted_kh_ahw", "ted_ca_ahw", "ted_cl_ahw", "ted_co_ahw", "ted_cr_ahw", "ted_hr_ahw", "ted_cy_ahw", "ted_cz_ahw", "ted_dk_ahw", "ted_ec_ahw", "ted_ee_ahw", "ted_fi_ahw", "ted_fr_ahw", "ted_de_ahw", "ted_gr_ahw", "ted_hk_ahw", "ted_hu_ahw", "ted_is_ahw", "ted_id_ahw", "ted_ie_ahw", "ted_il_ahw", "ted_it_ahw", "ted_jm_ahw", "ted_jp_ahw", "ted_lv_ahw", "ted_lt_ahw", "ted_lu_ahw", "ted_my_ahw", "ted_mt_ahw", "ted_mx_ahw", "ted_nl_ahw", "ted_nz_ahw", "ted_ng_ahw", "ted_no_ahw", "ted_pk_ahw", "ted_pe_ahw", "ted_ph_ahw", "ted_pl_ahw", "ted_pt_ahw", "ted_ro_ahw", "ted_ru_ahw", "ted_sg_ahw", "ted_sk_ahw", "ted_si_ahw", "ted_za_ahw", "ted_kr_ahw", "ted_es_ahw", "ted_lk_ahw", "ted_se_ahw", "ted_ch_ahw", "ted_tw_ahw", "ted_th_ahw", "ted_tt_ahw", "ted_tr_ahw", "ted_gb_ahw", "ted_us_ahw", "ted_uy_ahw", "ted_ve_ahw", "ted_vn_ahw")

#create empty vectors
values<-NULL
country<-NULL

#get last values 
for (i in list_of_series){
  values<-append(values, last(getValues(FetchOneTimeSeries(i))))
}

#get countries ISO codes
for (i in list_of_series){
  country<-append(country, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "Region"))
}

#change ISO codes to names
country<-countrycode(as.vector(country), origin="iso2c", destination ="country.name")

#prepare data frame
data <- data.frame(values, country) %>%
  arrange(values) %>% #this will sort data frame only
  mutate(country=factor(country, levels=country)) #for ggplot2 you need to plot factor levels too
data <- mutate(data, id=seq(from=1, to=nrow(data)))

#prepare labels data
label_data <- data

#calculate the ANGLE of the labels
number_of_bar <- nrow(label_data)
#subtract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
angle <-  90 - 360 * (label_data$id-0.5) /number_of_bar 

#calculate the alignment of labels: right or left
label_data$hjust<-ifelse(angle < -90, 1, 0)
#flip angle BY to make them readable
label_data$angle<-ifelse(angle < -90, angle+180, angle)

#chart
p <- ggplot(label_data, aes(x=country, y=values)) + 
  geom_bar(stat="identity", fill=alpha("#9054a5",1)) + #select color
  ylim(-800,3000)+
  coord_polar(start = 0)+
  theme_minimal() +
  theme(
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  )+
  geom_text(data=label_data, aes(x=id, y=values+5, label=country, hjust=hjust), 
            color="black", family="Helvetica", fontface="bold",alpha=1, size=1.7, angle= label_data$angle, inherit.aes = FALSE)+ #add country labels
  geom_text(data=label_data, aes(x=id, y=(-100), label=round(values,0), hjust=hjust), 
            color="black", family="Helvetica",alpha=1, size=1, angle=label_data$angle, inherit.aes = FALSE) #add value labels

#add title
p + ggtitle("Annual Hours Worked per Worker")+
  theme(plot.title = element_text(face="bold", size=12, hjust = 0.5))

Treemap

Macrobond R API is available for users with Data+ and Legacy license (the latter without searching and revision history functions). Examples were tested on Macrobond version 1.27, Macrobond API for R version 1.2-8 and R 4.3.0.

See two methods of constructing treemaps - with packages treemap and ggplot2 + treemapify. Examples are presented on Germany's export data from Federal Statistical Office (Statistisches Bundesamt).

 

 

 

 

Treemap version 1 and version 2 - both created with treemap package (click to enlarge). Jump to code with treemap package.

 

 

 

 

 

 

 

Treemap version 3 and version 4 with ggplot2 + treemapify packages (click to enlarge). Jump to code with ggplot2 + treemapify packages.

With treemap package

library(MacrobondAPI)
library(countrycode)
library(treemap)

#create list of series from Macrobond database
list_of_series<-c("detrad4162","detrad4163","detrad4164","detrad4165","detrad4166","detrad4167","detrad4168","detrad4169","detrad4170","detrad4171","detrad4172","detrad4173","detrad4174","detrad4175","detrad4176","detrad4177","detrad4178","detrad4179","detrad4180","detrad4181","detrad4182","detrad4183","detrad4184","detrad4185","detrad4186","detrad4187","detrad4188","detrad4189","detrad4190","detrad4191","detrad4192","detrad4193","detrad4194","detrad4195","detrad4196","detrad4197","detrad4198","detrad4199","detrad4200","detrad4201","detrad4202","detrad4203","detrad4204","detrad4205","detrad4206","detrad4207","detrad4208","detrad4209","detrad4210","detrad4211","detrad4212","detrad4213","detrad4214","detrad4215","detrad4217","detrad4218","detrad4219","detrad4220","detrad4221","detrad4222","detrad4223","detrad4224","detrad4225","detrad4226","detrad4227","detrad4228","detrad4229")

#create empty vectors
value <-NULL
group<-NULL

#get last values for each series
for (i in list_of_series){
value<-append(value, last(getValues(FetchOneTimeSeries(i))))
}

#get export countries ISO codes for each series based on TradeCounterpart metadata attribute
for (i in list_of_series){
group<-append(group, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "TradeCounterpart"))
}

#change ISO codes to names
group<-countrycode(as.vector(group), origin="iso2c", destination ="country.name")

#get continent for each country
continent<-countrycode(sourcevar = group, origin = "country.name",destination = "continent")

#create data
data <- data.frame(group, value)
data2 <- data.frame(continent, group, value)

#treemap version 1
treemap(data,
index="group",
vSize="value",
type="index",
palette = "Set3",
align.labels = c("left", "top"),
fontsize.labels=10,
fontcolor.labels="black",
title="Export of cars from Germany to... (in EUR)",
fontsize.title=18)

#treemap version 2 with by continent grouping
treemap(data2,
index=c("continent", "group"),
vSize="value",
type="index",
palette = "Set1",
fontsize.labels=c(0,10),
fontcolor.labels="white",
align.labels = c("left", "top"),
title="Export of cars from Germany to... (in EUR)",
fontsize.title=18)

With ggplot2 + treemapify packages

library(MacrobondAPI)
library(countrycode)
library(treemapify)
library(ggplot2)

#create list of series from Macrobond database
list_of_series<-c("detrad4162","detrad4163","detrad4164","detrad4165","detrad4166","detrad4167","detrad4168","detrad4169","detrad4170","detrad4171","detrad4172","detrad4173","detrad4174","detrad4175","detrad4176","detrad4177","detrad4178","detrad4179","detrad4180","detrad4181","detrad4182","detrad4183","detrad4184","detrad4185","detrad4186","detrad4187","detrad4188","detrad4189","detrad4190","detrad4191","detrad4192","detrad4193","detrad4194","detrad4195","detrad4196","detrad4197","detrad4198","detrad4199","detrad4200","detrad4201","detrad4202","detrad4203","detrad4204","detrad4205","detrad4206","detrad4207","detrad4208","detrad4209","detrad4210","detrad4211","detrad4212","detrad4213","detrad4214","detrad4215","detrad4217","detrad4218","detrad4219","detrad4220","detrad4221","detrad4222","detrad4223","detrad4224","detrad4225","detrad4226","detrad4227","detrad4228","detrad4229")

#create empty vectors
value <-NULL
group<-NULL

#get last values
for (i in list_of_series){
value<-append(value, last(getValues(FetchOneTimeSeries(i))))
}

#get export countries ISO codes for each series based on TradeCounterpart metadata attribute
for (i in list_of_series){
group<-append(group, getMetadataValues(getMetadata(FetchOneTimeSeries(i)), "TradeCounterpart"))
}

#change ISO codes to names
group<-countrycode(as.vector(group), origin="iso2c", destination ="country.name")

#get continent for each country
continent<-countrycode(sourcevar = group, origin = "country.name",destination = "continent")

#create data
data <- data.frame(group, value)
data2 <- data.frame(continent, group, value)

#treemap version 3 with legend
chart<-ggplot(data2, aes(area = value, fill = continent, label = group)) +
geom_treemap() +
geom_treemap_text(colour = "black", place = "centre", size = 12)+
ggtitle("Export of cars from Germany to... (in EUR)")+
theme(plot.title=element_text(size=20, face="bold"))

#color palette
chart+scale_fill_brewer(palette="PuBu")

#treemap version 4 with by continent grouping
chart<-ggplot(data2, aes(area = value, fill = continent, label = group, subgroup=continent)) +
geom_treemap() +
geom_treemap_subgroup_text(place = "centre", grow = TRUE, alpha = 0.25, colour = "black") +
geom_treemap_text(colour = "white", place = "centre", size = 12)+
ggtitle("Export of cars from Germany to... (in EUR)")+
theme(legend.position = "none", plot.title=element_text(size=20, face="bold"))

#MB color palette
conts<-c("Europe"="#256BA2", "Africa"="#F68D2E", "Oceania"="#CD545B", "Americas"="#8E51A8", "Asia"="#58A291")
chart+scale_fill_manual(values = conts)+
geom_treemap_subgroup_border(colour = "white", size = 3)