Instantly share code, notes, and snippets.

Embed
What would you like to do?
images as xaxis in R via LaTeX
library(rvest)
## GDP per capita, top 11 countries
n_countries <- 11
url <- "https://en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)_per_capita"
html <- read_html(url)
gdppc <- html_table(html_nodes(html, "table")[3])[[1]][1:n_countries, ]
## clean up; remove non-ASCII and perform type conversions
gdppc$Country <- gsub("Â ", "", gdppc$Country)
gdppc$Rank <- iconv(gdppc$Rank, "latin1", "ASCII", sub = "")
gdppc$Country <- iconv(gdppc$Country, "latin1", "ASCII", sub = "")
gdppc$`US$` <- as.integer(sub(",", "", gdppc$`US$`))
## flag images (yes, this processing could be done neater, I'm sure)
## get the 200px versions
flags_img <- html_nodes(html_nodes(html, "table")[3][[1]], "img")[1:n_countries]
flags_url <- paste0("http://", sub("[0-9]*px", "200px", sub('\\".*$', "", sub('^.*src=\\"//', "", flags_img))))
flags_name <- sub(".svg.png", ".png", sub(".*(Flag_of)", "\\1", flags_url))
## download each of the flags into a directory
if (!dir.exists("flags")) dir.create("flags")
for (flag in seq_along(flags_url)) {
switch(Sys.info()[["sysname"]],
Windows = {
download.file(flags_url[flag], destfile = file.path("flags", paste0(flag, "_", flags_name[flag])), method = "auto", mode = "wb")
},
Linux = {
download.file(flags_url[flag], destfile = file.path("flags", paste0(flag, "_", flags_name[flag])))
},
Darwin = {
print("Not tested on Mac. Use one of the above and find out?")
}
)
}
# /etc/ImageMagick-6/policy.xml
# <policy domain="coder" rights="none" pattern="PDF" />
# <policy domain="coder" rights="read|write" pattern="PDF" />
# https://stackoverflow.com/questions/42928765/convertnot-authorized-aaaa-error-constitute-c-readimage-453
library(magick)
## load the images from filenames
npoints <- length(flags_name)
pics <- vector(mode = "list", length = npoints)
image.file <- file.path(getwd(), dir("flags", full.names = TRUE))
image.file <- image.file[order(as.integer(sub("_.*", "", sub("^.*flags/", "", image.file))))]
for (i in 1:npoints) {
pics[[i]] <- image_read(image.file[i])
}
names(pics) <- sub(".svg.png", "", sub(".*Flag_of_", "", image.file))
names(pics)[8] <- "USA"
## create a dummy dataset
y <- gdppc$`US$`
x <- names(pics)
dat <- data.frame(x = factor(x, levels = names(pics)), y = y)
library(ggplot2)
## create the graph, as per normal now with @baptiste's adapted grob processing
## NB: #85bb65 is the color of money in the USA apparently.
gg <- ggplot(dat, aes(x = x, y = y / 1e3L, group = 1))
gg <- gg + geom_bar(col = "black", fill = "#85bb65", stat = "identity")
gg <- gg + theme_minimal()
gg <- gg + scale_fill_discrete(guide = FALSE)
gg <- gg + theme(plot.background = element_rect(fill = "grey90"))
gg <- gg + labs(title = "GDP per capita",
subtitle = "Top 11 countries",
x = "", y = "\\$US/1000", ## escaping for LaTeX
caption = paste0("\\shortstack{\\vspace{-1em}\\scriptsize{Source: ",
gsub("_", "\\\\_", url), "}}")) ## escaping for LaTeX
## use tikzDevice and include graphicx in the preamble
library(tikzDevice)
options(tikzLatexPackages = c(getOption("tikzLatexPackages"), "\\usepackage{graphicx}\n"))
## rather than typing this out every time, make it a function
make_label <- function(labels, files, scale = 0.2, offset = "2em") {
paste0("\\shortstack{\\includegraphics[scale=", scale, "]{",
files, "}\\\\\\hspace{-", offset,
"}\\rotatebox[origin=rt]{45}{\\small{", labels, "}}}")
}
## make some room for the images and caption
gg <- gg + theme(axis.text.x = element_text(size = 5,
lineheight = 0.9,
vjust = -4),
plot.margin = unit(c(5.5, 5.5, 12, 5.5), "points"))
## this is where most of the LaTeX magic is happening - the labels
gg <- gg + scale_x_discrete(breaks = names(pics),
labels = make_label(sub(".png", "", names(pics)), image.file))
## process the object with LaTeX and produce a PDF
tikz("xaxis.tex", standAlone = TRUE, width = 4, height = 4)
print(gg)
dev.off()
tools::texi2dvi("xaxis.tex", pdf = TRUE)
## convert the resulting PDF to a png using magick
image_read_pdf("xaxis.pdf") %>%
image_convert(format = "png") %>%
image_write("xaxis.png", density = 500)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment