Tommy Glizda
Tommy Glizda

Reputation: 23

Plot multiple stat functions on one ggplot using aesthetics

I have a data frame of parameters for distributions (here Im using a beta distribution but it could be any distribution really). Using beta1 and beta2 as the names of the two beta shape parameters (commonly referred to as alpha and beta)

df <- data.frame(dist = c("a", "b", "c"), beta1 = c(1,3,5), beta2 = c(3,3,3))

I would like to plot the pdf curves of all three of these on one graph, preferably with a legend per dist feature using ggplot2. If I do this manually I can do something like

p <- ggplot(data.frame(x = c(0,1)), aes(x)) +
  stat_function(fun = dbeta,
                colour = "red",
                args = list(
                  shape1 = 1,
                  shape2 = 3
                )) +
  stat_function(fun = dbeta,
                colour = "blue",
                args = list(
                  shape1 = 3,
                  shape2 = 3
                )) +
  stat_function(fun = dbeta,
                colour = "green",
                args = list(
                  shape1 = 3,
                  shape2 = 5
                ))

here's the plot output

but ideally would pass the beta1 and beta2 (shape1 and shape2) parameters using the ggplot aes functionality.

Upvotes: 0

Views: 73

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174468

You can't use aesthetics to map mutiple parameters directly into stat_function, but that doesn't mean that you need to pass all the parameters manually if you already have them stored in a data frame.

For example, using simple dplyr summarising you could do:

library(tidyverse)

df %>%
  group_by(dist) %>%
  summarise(x = seq(0, 1, 0.01), y = dbeta(x, beta1, beta2)) %>%
  ggplot(aes(x, y, color = dist)) +
  geom_line()

enter image description here

Or, if you really want to pass the values to stat_function, then using base R's Map you could do:

ggplot(df) +
  Map(function(dist, beta1, beta2) {
    stat_function(fun = dbeta, args = list(shape1 = beta1, shape2 = beta2),
                  aes(color = {{dist}}))
    }, df$dist, df$beta1, df$beta2) +
  labs(color = 'Distribution')

enter image description here

Upvotes: 1

Related Questions