Album artwork with ggplot2

“In 1984 I was hospitalized for approaching perfection…”  David Berman, 1998

And so begins the Silver Jews’ 1998 classic “American Water”, with possibly the greatest opening line to an album ever. But hey, you’ve probably not come here for a music review, you’ve come here for some ggplot2 fun! Right?! But firstly, I love this album, and I love the album cover:

I thought one day (in a slightly ggplot-obsessed state where I was seeing everything as aesthetics and geoms) that I could probably recreate this album art using only the power of R and the tidyverse. So here’s how I did it.

Set Up

There’s only one package I need for this:


I’m going to start by getting my colour palette sorted. I use a colour-picker add-in for Chrome (other web browsers are available) to get the hex-codes I want:

pal <- c(sky = "#6DA0BF", horizon = "#242430", road = "#ED5E72")

The mountain ranges on the horizon can be approximated using some random distributions. I’m not going to strive for perfection here (remember, in 1984 I was hospitalised for this).


range1 <- c(sort(runif(7, 0.25, 0.29)), sort(runif(3, 0.25, 0.31), decreasing = TRUE))
range2 <- runif(10, 0.28, 0.29)
range3 <- 0.27
range4 <- runif(10, 0.26, 0.27)
range5 <- c(sort(runif(3, 0.25, 0.29)), sort(runif(5, 0.25, 0.31), decreasing = TRUE))

These vectors are going to be used to make the horizon out of columns. Let’s put these vectors into one long vector, y, that will stretch across the x-axis from 0 to 1:

horizon <- tibble(x = seq(0, 1, 0.01),
                  y = c(rep(0.25, 10), range1, rep(0.25, 27), range2, rep(0.25, 2), 
                        range3, rep(0.25, 2), range4, rep(0.25, 12), range5, rep(0.25, 9)))

Next I’ll create the road that slowly disappears into the distance. To do this I will create a tibble of 4 x and y values that I will then feed into a geom_polygon:

road <- tibble(x = c(0.01, 0.49, 0.51, 0.99),
               y = c(0, 0.24, 0.24, 0))

The Plot

Now I can use these 2 tibbles (horizon and road) to make the plot. The horizon is built with geom_col and I will colour with the 2nd element in my palette vector. As I’ve said, the road is built with geom_polygon, again colouring with the corresponding colour in my palette. I played around with adding the band name in the top left, but I just couldn’t find a suitable font so I decided to leave it out:

ggplot(horizon, aes(x, y)) +
  # horizon
  geom_col(colour = pal[2], fill = pal[2]) +
  # road
  geom_polygon(data = road, aes(x, y), fill = pal[3]) +
  scale_x_continuous(expand = c(0, 0)) +
  # set limits of y axis
  scale_y_continuous(limits = c(0, 1), expand = c(0,0)) +
  # void themes
  theme_void() +
  # fill in background for sky
  theme(plot.background = element_rect(fill = pal[1]),
        plot.margin = margin(0, 0, 0, 0))


That was a fun task. It wasn’t completely frivolous either, as I did at least use geom_polygon which I had never used before. I find that working out how to replicate someone else’s plot (or album cover!) is a great way to practice ggplot2 skills. What album cover could you recreate using ggplot2? I put this out on twitter, and Harro Cyranka took on The Dark Side of the Moon. Nice!