2016-08-09 37 views
-1

正如标题所示,下面的函数绘制了传递数据中的多个密度图,并未绘制图例。 MWE:传说不使用ggplot2绘制多密度图

plotDensities <- function(xlab="", xlim=c(), ...) { 
    datas <- list(...) 
    cbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7") 
    if (length(datas) > length(cbPalette)) return(invisible(NULL)) 
    dplot <- ggplot() + xlab(xlab) + 
    scale_colour_manual(values=setNames(cbPalette[1:length(datas_names)], datas_names)) + 
    theme(legend.position = c(.8, .8)) 
    datas_names <- names(datas) 
    for (i in 1:length(datas)) { 
    name <- datas_names[i] 
    values <- data.frame(x=datas[[name]]) 
    dplot <- dplot + geom_density(aes(x=x), colour=cbPalette[i], data=values) 
    } 
    if (!is.null(xlim)) 
    dplot <- dplot + xlim(xlim) 

    return(invisible(dplot)) 
} 
v1 <- rnorm(2000, 0, 1) 
v2 <- rnorm(3000, 1, 1.5) 
v3 <- rnorm(4000, 2, 2.5) 
dplot <- plotDensities(xlim="whatever", v1=v1, v2=v2, v3=v3) 
dplot 

回答

1

ggplot产生图例当您在数据的列映射到内部aes美学(例如,colourfill等)。但是,在拨打geom_density时,您的代码在aes之外设置colour,这不会产生图例。

此外,您的数据被分成不同的向量。但是,如果以“长”格式存在单个数据帧,则ggplot的效果最佳。在这种情况下,这意味着将v1,0 v2v3组合成单个数据帧,而另一列标记每行最初来自哪个向量。

这里有一个简单的例子,使用你的数据,你可以调整到您的函数:

# Convert data to long format 
dat = data.frame(vals=c(v1,v2,v3), 
       source=rep(c("v1","v2","v3"),sapply(list(v1,v2,v3), length))) 

dat 
  vals source 
1 -0.2860619  v1 
2  1.8072476  v1 
3 -0.6492385  v1 
... 
8998 3.8989335  v3 
8999 5.1929588  v3 
9000 1.8716558  v3 
ggplot(dat, aes(vals, colour=source)) + 
    geom_density() + 
    scale_colour_manual(values=cbPalette[1:length(unique(dat$source))]) 

enter image description here

+0

优雅。改编。谢谢。 :) - 不确定为什么负面的投票,因为类似的东西是从另一个stackoverflow问题的公认的答案采取[链接](http://stackoverflow.com/questions/12199919/overlapped-density-plots-in-ggplot2)。 –

+0

很高兴工作。我不是低级选民,所以我不知道为什么。 – eipi10