Recreating ‘Unknown Pleasures’ graphic

[This article was first published on R | datawookie, 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.

For some time I’ve wanted to recreate the cover art from Joy Division’s Unknown Pleasures album. The visualisation depicts successive pulses from the pulsar PSR B1919+21, discovered by Jocelyn Bell in 1967.

Album art.

Data

The first obstacle was acquiring the data. I found a D3 visualisation by Mike Bostock. This in turn pointed me to a CSV file in a gist belonging to [@borgar](https://github.com/borgar).

After reading the CSV data into pulsar I applied some light wrangling (the raw data is a matrix).

library(dplyr)
library(tidyr)

pulsar <- read.csv(CSV, header = FALSE) %>%
  mutate(row = row_number()) %>%
  gather(col, height, -row) %>%
  mutate(
    col = sub("^V", "", col) %>% as.integer()
  )

Plot

Thanks to the ggridges package, making the plot was simple.

ggplot(pulsar, aes(x = col, y = row, height = height, group = row)) +
  geom_ridgeline(min_height = min(pulsar$height),
                 scale= 0.2,
                 size = 1,
                 fill = "black",
                 colour = "white") +
  scale_y_reverse() +
  theme_void() +
  theme(
    panel.background = element_rect(fill = "black"),
    plot.background = element_rect(fill = "black", color = "black"),
  )

A few things worth noting:

  1. To get the sense of the rows right I had to reverse the direction of the y-axis (this was also important to ensure that the animation reveals from top to bottom).
  2. It’s necessary to set both the color and fill for plot.background otherwise you get an irritating white outline.

Animation

Using transition_states() from the gganimate package I turned the static plot into an animation. I applied shadow_mark() with a value of alpha just below 1 to allow a small amount of transparency between each of the layers as the animation accumulates. This effect is not present in the original graphic, but I think that it’s informative to be able to see what’s happening “behind” each of the layers.

Epilogue

An anonymous contributor also sent me this version which uses only base R.

pulsar_matrix <- as.matrix(read.csv(CSV, header=F))

par(mar = c(0, 0, 0, 0))
plot(NULL, xlim = c(-100, 400), ylim = c(-10, 90), xaxs = 'i', yaxs = 'i')
rect(-105, -15, 405, 95, col = 'black')
for(i in 1:80) {
  polygon(
    c(1, 1:300, 300, 1),
    c(-1, 80 - i + pulsar_matrix[i,] / 10, -1, -1),
    col = 'black', border = 'white'
  )
}
segments(c(1, 300, 1), c(80, 80, -1),c(1, 300, 300), c(-1, -1, -1), col = 'black', lwd = 5)

To leave a comment for the author, please follow the link and comment on their blog: R | datawookie.

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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)