A Not So Simple Bar Plot Example Using ggplot2
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
This is a reproduction of the (simple) bar plot of chapter 6.1.1 in Datendesign mit R with ggplot2. To download the data you can use the following lines:
<pre class ="r"><code>dir.create("data") writeLines("*", "data/.gitignore") download.file("http://www.datendesign-r.de/alle_daten.zip", "data/alle_daten.zip") unzip("data/alle_daten.zip", exdir = "data") </code>
And to download the original script and the base R version of this plot:
<pre class ="r"><code>download.file("http://www.datendesign-r.de/beispielcode.zip", "data/beispielcode.zip") unzip("data/beispielcode.zip", exdir = "data") </code>
After downloading check out the original pdf version of this plot in data/beispielcode/pdf/balkendiagramm_einfach.pdf.
Preparing Data
Here are some steps to modify the data such that it can be easily used with ggplot2.
<pre class = "r"><code># remember to adjust the path ipsos <- openxlsx::read.xlsx("../data/alle_daten/ipsos.xlsx") ipsos <- ipsos[order(ipsos$Wert),] ipsos$Land <- ordered(ipsos$Land, ipsos$Land) ipsos$textFamily <- ifelse(ipsos$Land %in% c("Deutschland","Brasilien"), "Lato Black", "Lato Light") ipsos$labels <- paste0(ipsos$Land, ifelse(ipsos$Wert < 10, " ", " "), ipsos$Wert) rect <- data.frame( ymin = seq(0, 80, 20), ymax = seq(20, 100, 20), xmin = 0.5, xmax = 16.5, colour = rep(c(grDevices::rgb(191,239,255,80,maxColorValue=255), grDevices::rgb(191,239,255,120,maxColorValue=255)), length.out = 5)) </code>
The Basic Plot
First we add the geoms, then modifications to the scales and flip of the coordinate system. The remaining code is just modifying the appearance.
<pre class ="r"><code>library("ggplot2") ggBar <- ggplot(ipsos) + geom_bar(aes(x = Land, y = Wert), stat = "identity", fill = "grey") + geom_bar(aes(x = Land, y = ifelse(Land %in% c("Brasilien", "Deutschland"), Wert, NA)), stat = "identity", fill = rgb(255,0,210,maxColorValue=255)) + geom_rect(data = rect, mapping = aes(ymin = ymin, ymax = ymax, xmin = xmin, xmax = xmax), fill = rect$colour) + geom_hline(aes(yintercept = 45), colour = "skyblue3") + scale_y_continuous(breaks = seq(0, 100, 20), limits = c(0, 100), expand = c(0, 0)) + scale_x_discrete(labels = ipsos$labels) + coord_flip() + labs(y = NULL, x = NULL, title = NULL) + theme_minimal() + theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank(), axis.ticks = element_blank(), axis.text.y = element_text( family = ipsos$textFamily), text = element_text(family = "Lato Light")) ggBar </code>
Annotations and Layout
Of course you can simply add the title and text annotations to the plot using ggplot2, but I didn’t find a way to do the exact placement comparable to the original version without the package grid.
<pre class="r"><code>library("grid") vp_make <- function(x, y, w, h) viewport(x = x, y = y, width = w, height = h, just = c("left", "bottom")) main <- vp_make(0.05, 0.05, 0.9, 0.8) title <- vp_make(0, 0.9, 0.6, 0.1) subtitle <- vp_make(0, 0.85, 0.4, 0.05) footnote <- vp_make(0.55, 0, 0.4, 0.05) annotation1 <- vp_make(0.7, 0.85, 0.225, 0.05) annotation2 <- vp_make(0.4, 0.85, 0.13, 0.05) # To see which space these viewports will use: grid.rect(gp = gpar(lty = "dashed")) grid.rect(gp = gpar(col = "grey"), vp = main) grid.rect(gp = gpar(col = "grey"), vp = title) grid.rect(gp = gpar(col = "grey"), vp = subtitle) grid.rect(gp = gpar(col = "grey"), vp = footnote) grid.rect(gp = gpar(col = "grey"), vp = annotation1) grid.rect(gp = gpar(col = "grey"), vp = annotation2)</code>
And now we can add the final annotations to the plot:
<pre class ="r"><code># pdf_datei<-"balkendiagramme_einfach.pdf" # cairo_pdf(bg = "grey98", pdf_datei, width=9, height=6.5) grid.newpage() print(ggBar, vp = main) </code> <pre class ="r"><code>grid.text("'Ich glaube fest an Gott oder ein höheres Wesen'", gp = gpar(fontfamily = "Lato Black", fontsize = 14), just = "left", x = 0.05, vp = title) grid.text("...sagten 2010 in:", gp = gpar(fontfamily = "Lato Light", fontsize = 12), just = "left", x = 0.05, vp = subtitle) grid.text("Quelle: www.ipsos-na.com, Design: Stefan Fichtel, ixtract", gp = gpar(fontfamily = "Lato Light", fontsize = 9), just = "right", x = 0.95, vp = footnote) grid.text("Alle Angaben in Prozent", gp = gpar(fontfamily = "Lato Light", fontsize = 9), just = "right", x = 1, y = 0.55, vp = annotation1) grid.text("Durchschnitt: 45", gp = gpar(fontfamily = "Lato Light", fontsize = 9), just = "right", x = 0.95, y = 0.55, vp = annotation2) </code>
<pre class ="r"><code># dev.off()</code>
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.