Blog

# A Not So Simple Bar Plot Example Using ggplot2

12.12.2017 10:00

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:

``````dir.create("data")
writeLines("*", "data/.gitignore")
download.file("http://extras.springer.com/Zip/2018/978-3-662-54819-6.zip", "data/alle_daten.zip")
unzip("data/alle_daten.zip", exdir = "data")
``````

After downloading check out the original script of this plot in data/skripteunddaten/skripte/balkendiagramm_einfach.R.

## Preparing Data

Here are some steps to modify the data such that it can be easily used with ggplot2.

``````# remember to adjust the path
ipsos <- openxlsx::read.xlsx("./data/skripteunddaten/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))
``````

## 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.

``````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
``````

## 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.

``````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)``````

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

``````# pdf_datei<-"balkendiagramme_einfach.pdf"
# cairo_pdf(bg = "grey98", pdf_datei, width=9, height=6.5)

grid.newpage()
print(ggBar, vp = main)
``````
``````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)
``````

``# dev.off()``

Go back