Search code examples
rggplot2kernel-density

use ggplot2 with kde plots of ks package


I'm using ks package to calculate and plot bivariate kernel density estimations. It works great, but I want to use ggplot to plot the estimations instead.

I could try and create a custom function to prepare a data frame and stuff for ggplot but I have a feeling more experienced users of R could do this with less effort.

So, how do I do it?

Here is an example scenario of ks::kde:

data <- cbind(rnorm(100), rnorm(100))
kd <- ks::kde(data)
plot(kd, display = "slice", col = viridis::viridis(20))
plot(kd, display = "image", col = viridis::viridis(20))
plot(kd, display = "persp", col.fun = viridis::viridis)

The above code should give you the following plots. How do I use ggplot to achive these plots?

EDIT: I need to use the estimations calculated by ks package. The native functions provided by ggplot2 uses a package named MASS. So that won't do.

slice plot image plot perspective plot


Solution

  • The first two are straightforward in ggplot. Here's a fully reproducible example:

    library(ggplot2)
    
    data <- cbind(rnorm(100), rnorm(100))
    
    d <- ggplot(as.data.frame(data), aes(V1, V2)) + 
      scale_color_viridis_c() +
      theme_bw()
    
    d + geom_density2d(aes(colour = after_stat(level)), bins = 5)
    

    d + geom_density2d_filled()
    


    EDIT

    To specifically use the output of ks::kde(), we need to convert its data from a matrix into long format using reshape2::melt, but then it is still very easy to plot in ggplot:

    set.seed(1)
    
    data <- cbind(rnorm(100), rnorm(100))
    kd   <- ks::kde(data)
    
    library(ggplot2)
    

    Contour Plot

    ggplot(reshape2::melt(kd$estimate)) +
      geom_contour(aes(x = Var1, y = Var2, z = value, color = stat(level)),
                   bins = 5) +
      scale_color_viridis_c() +
      coord_equal() +
      theme_classic()
    

    Filled contour plot

    ggplot(reshape2::melt(kd$estimate)) +
      geom_contour_filled(aes(x = Var1, y = Var2, z = value, fill = stat(level)),
                   bins = 9) +
      scale_fill_viridis_d() +
      coord_equal() +
      theme_classic() +
      theme(legend.position = "none")
    

    Raster image

    ggplot(reshape2::melt(kd$estimate)) +
      geom_raster(aes(x = Var1, y = Var2, fill = value)) +
      scale_fill_viridis_c() +
      coord_equal() +
      theme_classic() +
      theme(legend.position = "none")
    

    Created on 2021-11-12 by the reprex package (v2.0.0)