rggplot2

How to create a shaded 2d density plot in ggplot2 and R


I would like to create a 2d density plot where depth of color represents density.

So for the data set

x1 <- rnorm(100, mean=0)
y1 <- rnorm(100, mean=0)
x2 <- rnorm(100, mean=4)
y2 <- rnorm(100, mean=4)

df <- data.frame(x = c(x1, x2), y=c(y1, y2), cat=rep(c("A", "B"), each=100))

I could make a contour plot

ggplot(df, aes(x=x, y=y, color=cat)) + geom_density2d()

2d contour plot of example data

...but instead of contours, I'd like for the image to have a strong orange color at the peak of the cat="A" data, fading out to transparency as the density decreases, and a strong cyan color at the peak of the cat="B" data, fading out as the density decreases.

It seems like some combination of geom_tile() and aes(alpha=cat) would do this, but I can't quite figure it out.


Solution

  • Do this:

    # Create density plot with custom colors for categories A and B
    ggplot(df, aes(x = x, y = y)) +
      stat_density_2d(
        aes(fill = cat, alpha = after_stat(level)), 
        geom = "polygon",
        color = NA
      ) +
      scale_fill_manual(
        values = c("A" = "darkorange", "B" = "cyan2"),
        name = "Category",  # Legend title
        guide = "legend"
      ) +
      scale_alpha(range = c(0, 0.5), guide = "none") 
    

    refer this for colors.

    out


    For completenes, me personally I would do something like this:

    # Create density plot with custom colors and density outlines
    ggplot(df, aes(x = x, y = y)) +
      stat_density_2d(
        aes(fill = cat, alpha = after_stat(level)), 
        geom = "polygon",
        color = NA
      ) +
      geom_density_2d(
        aes(color = cat), 
        size = 0.5,  # Line thickness for the contours
        linetype = "solid"
      ) +
      scale_fill_manual(
        values = c("A" = "darkorange", "B" = "cyan2"),
        name = "Category",  # Legend title
        guide = "none"
      ) +
      scale_alpha(range = c(0.0, 1), guide = "none") +
      scale_color_manual(
        values = c("A" = "darkorange", "B" = "cyan2")
      ) +
      theme_minimal() +
      labs(title = "2D Density Plot by Category with Density Outlines",
           x = "X",
           y = "Y")
    

    gives you a clearer picture! out2