Search code examples
rggplot2graphdensity-plotbubble-chart

Compound 2d density + bubble plot in R w/ ggplot 2


TLDR; Can I force the bubble coordinates onto a uniform grid?

I've made this figure to visualize the relationship between physical oceanographic variables (SST and HCI) and the total number of fish caught (landings). SST is sea surface temperature, and HCI is habitat compression index. The coordinates of the bubbles are HCI ~ SST, and bubble size is scaled by landings. My reference code is down the bottom.

SST is sea surface temperature, and HCI is habitat compression index. The coordinates of the bubbles are HCI ~ SST, and bubble size is scaled by landings.

You can see that the fishery has "boom-bust" periods, i.e. there are many small-medium bubbles and a few very large ones. These larger bubbles tend to be when HCI is low and SST is high. Both HCI and SST are significant in predicting landings.

I like the figure but it's very "noisy", with the bubbles overlapping so much. Is there a way that I can force them onto a uniform grid? I've tried geom_bin2d, but that broke the background density plot.

Here's a reference figure that show's what I'm trying to do. Obviously my figure is fundamentally different, but this looks like the figure that I'm trying to make.

From Phillips et al. 2014, Spatio-temporal associations of albacore CPUEs in the Northeastern Pacific with regional SST and climate environmental variables

Here's my code:

# HCI ~ SST density plot, as the background
background_plot <- ggplot(path_data, aes(x = SST, y = HCI)) +
  stat_density_2d(aes(fill = ..density..), geom = "raster", contour = FALSE) +
  scale_fill_continuous(type = "viridis") +
  theme_gray() +
  ylim(-0.1, 1)

# Add bubbles, scaled by # landings
bubble_chart <- background_plot +
  geom_point(data = path_data, aes(x = SST, y = HCI, size = SUM_RETAINED_NUM, color = SUM_RETAINED_NUM), 
             alpha = 0.6) +
  scale_size_continuous(range = c(1, 10), guide = "legend") +
  scale_color_cmocean(name = "ice", direction = 1, guide = "legend") +
  theme_gray()

# Combined plot
bubble_chart

Solution

  • geom_point(data = dplyr::count(path_data, 
                                   SST = round(SST*10)/10, 
                                   HCI = round(HCI*20)/20, 
                                   wt = SUM_RETAINED_NUM, 
                                   name = "SUM_RETAINED_NUM"), 
               aes(x = SST, y = HCI, size = SUM_RETAINED_NUM, color = SUM_RETAINED_NUM), 
               alpha = 0.6) +
    

    should make the points be summed by buckets, where here I've rounded SST to the closest 1/10th unit, and HCI to the closest 1/20th unit. Adjust to taste.

    BTW, shape = 21 can get you something more like your example if you want hollow points.