Search code examples
rggplot2histogram

Marginal histogram of third dimension in ggplot2? Or histogram for legend?


If we use ggplot2, and ggExtra, on a scatterplot, the ggMarginal will add marginal histograms, but only for X and Y dimensions.

I want to add a histogram onto the color legend. Say we have 3 dimensions, x,y,z. The scatterplot displayes x,y as location, and then z as color. We then have a legend concerning the color of points. Is there a way to add a histogram to the legend, so that the viewer can see relative frequency beyond just guessing from visual interpretation of color?

Starting point:

x = c(rnorm(100, 2, 2), rnorm(100, -1, 3))
y = c(rnorm(100, -1, 3), rnorm(100, 2, 1))
z = c(rnorm(50, -2, 2), rnorm(100, 1, 1), rnorm(50, 3, 2))

d = data.frame(x, y, z)
library(ggplot2)
ggplot(d, aes(x = x, y = y, color = z)) + geom_point() + scale_color_viridis_c()

I want to add a histogram to the legend for z. Any idea how?


Solution

  • Maybe something like this, using patchwork to give a rotated geom_histogram an arbitrary 1/6th of the width of the available space?

    library(patchwork)
    library(ggplot2)
    library(scales)
    
    x = c(rnorm(100, 2, 2), rnorm(100, -1, 3))
    y = c(rnorm(100, -1, 3), rnorm(100, 2, 1))
    z = c(rnorm(50, -2, 2), rnorm(100, 1, 1), rnorm(50, 3, 2))
    d = data.frame(x, y, z)
    
    p1 <- ggplot(d, aes(x = x, y = y, color = z)) + 
      geom_point(show.legend = F) + 
      scale_color_viridis_c()
    
    p2 <- ggplot(d, aes(y = z, fill = after_stat(y))) + 
      geom_histogram(show.legend = F, bins = 21) + 
      scale_fill_viridis_c() +
      scale_y_continuous(breaks = pretty_breaks(n = 8)) +
      labs(y = "Histogram Legend for z", x = NULL) +
      theme(
        panel.background = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        )
    
    p1 + p2 + plot_layout(widths = c(5, 1))
    

    Created on 2024-04-28 with reprex v2.1.0