Skip to content

Latest commit

 

History

History
executable file
·
142 lines (107 loc) · 3.8 KB

weepeople_dotplots.md

File metadata and controls

executable file
·
142 lines (107 loc) · 3.8 KB

Dotplots of Wee People

Matthew Kay 2022-04-27

Introduction

This demo shows the use of the Wee People font from ProPublica with geom_dots() from ggdist. The idea of using Wee People with dotplots comes from @gdbassett, and the code is based on @hrbrmstr’s example code for using custom fonts in ggplot.

Setup

The dev version of ggdist is needed to run this example. Install it with:

remotes::install_github("mjskay/ggdist")

These libraries are needed:

library(systemfonts)
library(ggplot2)
library(ggdist)

theme_set(theme_ggdist())
knitr::opts_chunk$set(dev = "png", dev.args = list(png = list(type = "cairo")))

Font setup

Download the Wee People font:

download.file(
  url = "https://github.com/propublica/weepeople/raw/master/weepeople.ttf",
  destfile = "weepeople.ttf"
)

And register it so we can use it with family = "weepeople":

register_font(
  name = "weepeople",
  plain = "weepeople.ttf"
)

Wee People Dotplots

An example with raw data using geom_dots():

set.seed(1234)

df = data.frame(
  x = qnorm(ppoints(100), 1:2),
  set = c("a", "b"),
  icon = factor(sample(52, 100, replace = TRUE))
) 

# the lower and upper case letters in the Wee People font are people:
people = c(letters, toupper(letters))

df |>
  ggplot(aes(x = x, y = set, group = set, shape = icon)) + 
  geom_dots(family = "weepeople") + 
  scale_shape_manual(values = people, guide = "none")

Notice how the people are spaced out horizontally. This is because compared to normal dots, which have a square aspect ratio, they are quite tall. With geom_dots(), stackratio determines vertical stacking and dotsize horizontal spacing, so if we increase dotsize we can make them be spaced closer together (fortunately the automatic bin width selection algorithm will account for this and adjust binwidth accordingly):

df |>
  ggplot(aes(x = x, y = set, group = set, shape = icon)) + 
  geom_dots(family = "weepeople", dotsize = 2.4) + 
  scale_shape_manual(values = people, guide = "none")

We can also make it feel a bit more organic using the "swarm" layout:

df |>
  ggplot(aes(x = x, y = set, group = set, shape = icon, color = x > 0)) + 
  geom_dots(family = "weepeople", dotsize = 2.4, layout = "swarm")+#, binwidth = 0.145) + 
  scale_shape_manual(values = people, guide = "none") +
  scale_color_brewer(palette = "Set1", guide = "none")

For completeness, an example with an analytical distribution using stat_dots():

data.frame(x = distributional::dist_normal(0,1)) |>
  ggplot(aes(xdist = x, shape = stat(factor(1:50)))) + 
  stat_dots(quantiles = 50, family = "weepeople", dotsize = 2.4) + 
  scale_shape_manual(values = people, guide = "none")

Bonus

Bonus: emoji dotplots using {ragg}

ragg::agg_png("weepeople_dotplots_files/emoji-ragg.png", width = 1344, height = 960, res = 200)
print(df |>
  ggplot(aes(x = x, y = set, group = set, color = x > 0)) + 
  geom_dots(aes(shape = x > 0), layout = "weave", dotsize = 0.9, stackratio = 1.1, fill = NA, position = position_nudge(x = 0.07)) + 
  scale_shape_manual(values = c("💩", "😺"), guide = "none") +
  scale_color_brewer(palette = "Set1", guide = "none")) +
  geom_vline(xintercept = 0)
dev.off()
## png 
##   2