2

I have the following script:

library(ggplot2)

values <- c(0.1,0.15,0.2,0.3,0.5,1,1.5,2,2.5)
colours <- palette()[1:length(values)];


p <- ggplot(data.frame(x=c(0, 2)), aes(x)) +
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 0.1),aes(colour="0.1"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 0.15),aes(colour="0.15"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 0.2),aes(colour="0.2"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 0.3),aes(colour="0.3"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 0.5),aes(colour="0.5"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 1),aes(colour="1"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 1.5),aes(colour="1.5"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 2),aes(colour="2"))+
  stat_function(fun= function(x) dlnorm(x,mean = 0, sd = 2.5),aes(colour="2.5"))+
  scale_colour_manual("Sigma:", values=colours, breaks=as.character(values))

p

Which produces the following graph (minus the title) of how the log-normal distribution looks like for different values of a parameter:

graph of log-normal distribution

How can I replace those copy-pasted lines with something more eye-friendly?

Something like stat_function(fun= function(x) dlnorm(x,mean = 0, sd = values),aes(colour=as.character(values)))

Edit: Unlike the question that was suggested as duplicate, I'm handling functions, not data, so I'm not sure how to apply the suggestions there


I also tried in a for-loop like this:

library(ggplot2)

values <- c(0.1,0.15,0.2,0.3,0.5,1,1.5,2,2.5)
colours <- palette()[1:length(values)];


p <- ggplot(data.frame(x=c(0, 2)), aes(x)) +
  ggtitle(expression(paste("Log-normaal distributie met verschillende waarden van ", sigma)))+
  ylab(expression(paste(f[X](x)))) 


for(i in 1:length(values)){
  p <- p + stat_function(fun= function(x) dlnorm(x,mean = 0, sd = values[i]), aes(colour=as.character(values[i])))
}


p +   scale_colour_manual("Sigma:", values=colours, breaks=as.character(values))

But it doesn't work: it only plots the last curve.


I also tried as the an answer suggested, which works fine, but I'm then unable to add labels to the colours:

ggplot(data.frame(x=c(0, 2)), aes(x)) + 
  mapply(function(col, mean, sd) {
    stat_function(fun = dlnorm, args = list(mean = mean, sd = sd), aes(colour=col))}, 
    mean = 0, sd = values, col = as.character(values)) +
  scale_colour_manual("Sigma:", values=colours, breaks=as.character(values))

It produces an error saying: Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : arguments imply differing number of rows: 0, 2

Gloomy
  • 1,091
  • 1
  • 9
  • 18
  • 1
    Possible duplicate of [how to add layers in ggplot using a for-loop](https://stackoverflow.com/questions/15987367/how-to-add-layers-in-ggplot-using-a-for-loop) – LAP Dec 13 '17 at 11:10
  • @LAP: I saw that question, but couldn't make it work. I don't have data, but rather continuous curves plotted from a function... – Gloomy Dec 13 '17 at 11:26

1 Answers1

4

Hope this helps!

library(ggplot2)

values <- c(0.1, 0.15, 0.2, 0.3, 0.5, 1, 1.5, 2, 2.5)
colours <- c(palette(), "orange");

ggplot(data.frame(x=c(0, 2)), aes(x)) + 
  mapply(function(col, mean, sd) {
    stat_function(fun = dlnorm, args = list(mean = mean, sd = sd), colour = col)}, 
    mean = 0, sd = values, col = colours)

Edit update:
Seems if you want to have color legend with stat_function then you need to repeat it multiple times rather than putting it in for loop or mapply.


Just in case you are interested in another solution then you may try below chunk of code:

library(dplyr)
library(ggplot2)

df <- data.frame(mean = rep(0,9),
                 sd = c(0.1, 0.15, 0.2, 0.3, 0.5, 1, 1.5, 2, 2.5))
colours <- c(palette(), "orange");

x <- seq(0,2,0.01)
my_func <- mdply(df, function(mean,sd){
  data.frame(x=x, y=dlnorm(x,mean, sd), sigma=as.character(sd))}) %>% 
  bind_rows

ggplot(my_func, aes(x=x, y=y, colour=sigma)) + 
  geom_line() +
  scale_colour_manual(values=colours) +
  theme_bw()

Output plot

Prem
  • 11,775
  • 1
  • 19
  • 33
  • That helps indeed, however it breaks when I try to add labels for the colours (see edited question) – Gloomy Dec 13 '17 at 11:56