HannesZ
HannesZ

Reputation: 609

Assign color in ggplot aes to the color parameter of stat_function

Lets say I want to create a histogram with color aes and I have several functions fitted for each of the factor-levels of the column that I use for the color aes.

Sorry for the complicated description, here is an example:

library(ggplot2)
set.seed(1234)
wdata = data.frame(
  sex = factor(rep(c("F", "M"), each=200)),
  weight = c(rnorm(200, 55), rnorm(200, 58)))
head(wdata)

fun_f <- function(x){dnorm(x, mean = 55)}
fun_m <- function(x){dnorm(x, mean = 58)}

p <- ggplot(wdata, aes(x = weight, color=sex, fill = sex)) + 
  geom_histogram(aes(color = sex),position = "dodge", bins = 30)+
  stat_function(fun=function(x){ 
    fun_m(x)*60
  }, 
  geom="line",
  color ="blue",
  size = 1)+

  stat_function(fun=function(x){ 
    fun_f(x)*60
  },
  color ="red",
  geom="line",
  size = 1)

p

My goal now is to use the color for wdata[sex=="f"] for fun_f instead of color="red". Analogously for fun_m.

Is that possible?

Upvotes: 1

Views: 1203

Answers (1)

camille
camille

Reputation: 16832

stat_function takes an aes mapping just like any other ggplot layer, so it will actually inherit the color = sex, fill = sex that you set initially.

However, to get stat_function to recognize the different values for sex that are in the data, you can filter in the data argument. If you think about it, your function is independent of the actual data, so there otherwise isn't anything happening to say one curve should be drawn for "M" and one for "F" until you trigger it manually. Then set the colors you want in both the color and fill scales.

library(ggplot2)
library(dplyr)

ggplot(wdata, aes(x = weight, color = sex, fill = sex)) +
  geom_histogram(position = "dodge") +
  stat_function(fun = function(x) fun_m(x) * 60, data = . %>% filter(sex == "M")) +
  stat_function(fun = function(x) fun_f(x) * 60, data = . %>% filter(sex == "F")) +
  scale_color_manual(values = c("F" = "red", "M" = "blue")) +
  scale_fill_manual(values = c("F" = "red", "M" = "blue"))

Created on 2019-02-25 by the reprex package (v0.2.1)

Upvotes: 2

Related Questions