Site icon R-bloggers

A Not So Simple Bar Plot Example Using ggplot2

[This article was first published on INWT-Blog-RBloggers, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
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></pre>

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></pre>

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 &lt;- openxlsx::read.xlsx("../data/alle_daten/ipsos.xlsx")  ipsos &lt;- ipsos[order(ipsos$Wert),] ipsos$Land &lt;- ordered(ipsos$Land, ipsos$Land) ipsos$textFamily &lt;- ifelse(ipsos$Land %in% c("Deutschland","Brasilien"),                            "Lato Black", "Lato Light") ipsos$labels &lt;- paste0(ipsos$Land, ifelse(ipsos$Wert &lt; 10, "     ", "  "),                        ipsos$Wert) rect &lt;- 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></pre>

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 &lt;- 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></pre>

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 &lt;- function(x, y, w, h)    viewport(x = x, y = y, width = w, height = h, just = c("left", "bottom")) main &lt;- vp_make(0.05, 0.05, 0.9, 0.8) title &lt;- vp_make(0, 0.9, 0.6, 0.1) subtitle &lt;- vp_make(0, 0.85, 0.4, 0.05) footnote &lt;- vp_make(0.55, 0, 0.4, 0.05) annotation1 &lt;- vp_make(0.7, 0.85, 0.225, 0.05) annotation2 &lt;- 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></pre>

And now we can add the final annotations to the plot:

<pre class ="r"><code># pdf_datei&lt;-"balkendiagramme_einfach.pdf" # cairo_pdf(bg = "grey98", pdf_datei, width=9, height=6.5) grid.newpage() print(ggBar, vp = main) </code></pre>
<pre class ="r"><code>grid.text("'Ich glaube fest an Gott oder ein höheres Wesen'",           gp = gpar(family = "Lato Black", size = 14),           just = "left", x = 0.05, vp = title) grid.text("...sagten 2010 in:",           gp = gpar(family = "Lato Light", size = 12),           just = "left",           x = 0.05, vp = subtitle) grid.text("Quelle: www.ipsos-na.com, Design: Stefan Fichtel, ixtract",           gp = gpar(family = "Lato Light", size = 9),           just = "right",           x = 0.95, vp = footnote) grid.text("Alle Angaben in Prozent",           gp = gpar(family = "Lato Light", size = 9),           just = "right",           x = 1, y = 0.55, vp = annotation1) grid.text("Durchschnitt: 45",           gp = gpar(family = "Lato Light", size = 9),           just = "right",           x = 0.95, y = 0.55, vp = annotation2) </code></pre>

<pre class ="r"><code># dev.off()</code></pre>

To leave a comment for the author, please follow the link and comment on their blog: INWT-Blog-RBloggers.

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.