rggplot2plotggforce

Trouble making a particular sampling schematic diagram using ggplot2 and ggforce


I've been trying to make a reproducible version of a diagram of the sampling scheme for a particular field project, mirroring this version that I made by hand in PowerPoint:

Original sampling schematic figure

Geom_mark_rect from ggforce has been super helpful for creating boxes around the collections of points. However, I've been having trouble making the boxes fit more tightly around the points (and not being forced to squares); when I try to make a similarly narrow version of the R figure, the boxes overlap:

Current R sampling schematic figure

It would be great if there were a way to make the geom_mark_rect boxes tighter around the points; any advice on parameters to change or things to try would be greatly appreciated. Or, other creative approaches to trying to make this diagram via ggplot would be so helpful!

The code used to produce the current R figure is below, where data_forchart can be imported from the attached .csv:

facet.labs =  c("Tide Pool 1\n (S1)", "Tide Pool 2\n (S2)", "Nearshore\n (N)")
names(facet.labs) = c("S1", "S2", "N")

data_forchart$Location= factor(data_forchart$Location, levels=c("S1", "S2", "N"))
data_forchart$chart_num= factor(data_forchart$chart_num, levels=c("3", "2", "1"))


sample_schema = ggplot(data = data_forchart, aes(x = Time, y = chart_num, shape = Location, color = Time, fill = Time)) + 
  geom_beeswarm(cex= 2, size = 3) + 
  geom_mark_rect(expand = .03) +
  scale_shape_manual(values = c(15, 17, 16)) + 
  viridis::scale_color_viridis(discrete=TRUE, begin = 0, end = .97, direction = -1) +
  viridis::scale_fill_viridis(discrete=TRUE, begin = 0, end = .97, direction = -1) +
  facet_grid(Location ~., scales = "free_y", space = "free_y", switch = "y", labeller = labeller(Location = facet.labs)) +
  theme_void(base_size = 16) + 
  theme(legend.position = "none") +
theme(strip.text.y.left = element_text(angle = 0, hjust = 1, vjust = .9)) 

data_forchart


Solution

  • It seems quite fiddly getting geom_mark_rect to adopt a particular aspect ratio. It would be nice if geom_rect had the option to have rounded corners, but it doesn't. You can instead use geom_box from ggh4x

    library(ggforce)
    library(ggh4x)
    library(ggbeeswarm)
    
    ggplot(data = data_forchart, aes(x = Time, y = chart_num, shape = Location,
                                     color = Time, 
                                     fill = after_scale(alpha(colour, 0.05)))) + 
      geom_beeswarm(cex = 2, size = 4) + 
      geom_box(aes(xmin = after_stat(x) - 0.45, 
                                 xmax = after_stat(x) + 0.45,
                                 ymin = after_stat(y) - 0.4, 
                                 ymax = after_stat(y) + 0.45),
                             radius = unit(5, "pt")) +
      scale_shape_manual(values = c(15, 17, 16)) + 
      scale_color_viridis_d(direction = -1) +
      facet_grid(Location ~., scales = "free_y", space = "free_y", 
                 switch = "y", labeller = labeller(Location = facet.labs)) +
      theme_void(base_size = 16) + 
      theme(legend.position = "none",
            strip.text.y.left = element_text(angle = 0, hjust = 1, vjust = .9)) 
     
    

    enter image description here