Created
October 16, 2018 11:16
-
-
Save jonocarroll/08a1ccff36be628430d768e5b9426e54 to your computer and use it in GitHub Desktop.
images as xaxis in R via LaTeX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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