Search code examples
rggplot2permutationdice

Plot all permutations of two discontinuous ranges


I'd like to plot all possible outcomes of rolling two unconventional six-sided dice:

die_1 <- c(0, 1, 2, 3, 6, 6)
die_2 <- c(0, 0, 0, 6, 6, 6)

And colour by which die rolls higher for each permutation.

The result would look like this:

enter image description here

So far, I have tried:

library(tidyverse)
expand_grid(die_1, die_2) %>% 
  mutate(winner = if_else(die_1 > die_2, "die_1", if_else(die_1 == die_2, "draw", "die_2"))) %>%
  ggplot(aes(x = die_1, y = die_2, fill = winner)) +
  geom_point(aes(colour = winner), size = 10, shape = "square") +
  scale_discrete_manual(aesthetics = "colour", values = c("orange", "blue", "grey")) +
  scale_y_reverse(breaks = c(0:6)) +
  scale_x_continuous(position = "top", breaks = c(0:6)) 

imgur my ggplot2 version

enter image description here

So I'm trying to put the permutations on the x and y axes, but ggplot2 plots the outcomes, which creates overplotting. Please compare the images if I'm not explaining myself.

Does anyone have an idea how this could be made in ggplot2?


Solution

  • A solution is to add two helper columns not with the outcome of the die roll, but with which side was facing up. Then you can plot the rolled sides on the axis and change the labels to the outcomes. If you want to get closer to the aesthetic of your original plot using geom_tile might be easier. There probably is a nicer way to do this, but this works here:

    die_1 <- c(0, 1, 2, 3, 6, 6)
    die_2 <- c(0, 0, 0, 6, 6, 6)
    
    expand_grid(die_1, die_2) %>% 
      mutate(die_1_side = c(rep(1,6),rep(2,6),rep(3,6),rep(4,6),rep(5,6), rep(6,6)),
             die_2_side = c(rep(c(1,2,3,4,5,6), 6) )) %>%
      mutate(winner = if_else(die_1 > die_2, "die_1", if_else(die_1 == die_2, "draw", "die_2"))) %>%
      ggplot(aes(x = die_1_side, y = die_2_side, fill = winner)) +
      geom_tile(aes(fill = winner), color = "white", size = 1) +
      scale_discrete_manual(aesthetics = "fill", values = c("orange", "blue", "grey")) +
      scale_y_reverse(breaks = c(1:6), labels = c(0,0,0,6,6,6)) +
      scale_x_continuous(position = "top", breaks = c(1:6), labels = c(0,1,2,3,6,6))
    

    enter image description here