Day 35: Accidental art with scico

A few days ago, while trying to draw a nice contour plot for a paper, I accidentally discovered that when you ask the stat_density_2d function to use geom = "polygon" to draw a two dimensional kernel density estimate, it is terribly literal in how it defines polygons. If the line that defines a particular contour runs outside the plot area, it treats it as the end of the line, so the relevant polygon is closed then and there, so to speak. This isn’t terribly helpful for drawing density plots, I suppose, but it did lead to some accidental artwork:

At about the same time I saw a whole bunch of folks on twitter talking about the scico package, which provides an R implementation of scientific colour palettes that aim to be (a) perceptually uniform and (b) colour-blind friendly. I like both of those properties a good deal - and after the drawn out post from yesterday I reeeeaaaaally need to do a light and fluffy post - so I decided that a natural thing to do would be to use the scico package to draw coloured versions of my accidental artwork.

First up, I’ll define a function cut_out that generates data from a mixture of three bivariate normal distributions, computes a kernel density estimate, and then deliberately abuses that by setting the axis bounds too narrow. It takes a single argument palette that specifies the name of one of the scico palettes that it will use to draw the contour polygons.

library(scico)
library(ggplot2)
library(magrittr)

cut_out <- function(palette) {
  
  # means for mixture of gaussians
  mu_x <- c(0,4,0)
  mu_y <- c(0,2,4)
  
  # samples from mixtures of gaussians
  n <- 200
  df <- data.frame(
    x = rnorm(n*3),
    y = rnorm(n*3)
  )
  for(i in 1:3) {
    ind <- (1:n) + (i-1)*n
    df$x[ind] <- df$x[ind] + mu_x[i]
    df$y[ind] <- df$y[ind] + mu_y[i]
  }
  
  # draw a picture that deliberately misuses the geom = "polygon"
  # option to stat_density_2d
  pic <- df %>%
    ggplot(aes(x,y,fill = ..level..)) +
    theme_void() +
    stat_density_2d(geom="polygon") + 
    xlim(0+rnorm(1),4+rnorm(1)) + 
    ylim(0+rnorm(1),4+rnorm(1)) +
    ggtitle(palette) +
    scale_fill_scico(name="",labels=NULL, palette = palette)
  
  plot(pic)
  #return(invisible(pic))
  
}

Next, here are the names of all the palettes in the scico package:

scico_palette_names()
##  [1] "berlin"  "bilbao"  "broc"    "cork"    "davos"   "devon"   "grayC"  
##  [8] "lajolla" "lapaz"   "lisbon"  "oleron"  "oslo"    "roma"    "tofino" 
## [15] "tokyo"   "turku"   "vik"

Finally, I’ll call the cut_out function once for each palette:

for(palette in scico_palette_names()) {
  cut_out(palette)
}

Prettiness!

Avatar
Danielle Navarro
Associate Professor of Cognitive Science

Related