在循环中运行boxplots / horizo​​ntal lines时,hline索引没有改变的麻烦

时间:2016-06-16 00:41:33

标签: r ggplot2 legend

我已经搜索了很长时间才找到解决方案但无济于事。我正在绘制一个框图,在循环中ggplot2中有一些水平线。我想出了线条美学设置"颜色"作为我想在传奇中找到的名称,以获得线条和箱形图的图例。但是,行索引值似乎没有更新,绘制的是所有绘图上的相同行值,特别是循环中最后一项的值。

我使用iris数据集重现了以下问题:

library(dplyr)
library(ggplot2)
library(tidyr)
liris<-gather(iris,"Param","Value",1:4)
liris<-as.data.frame(liris)

indices<-unique(liris$Param)
plot_list<-list()
for (i in indices) {
sub<-filter(liris,Param==i)

min<-min(sub$Value)
max<-max(sub$Value)

g<-ggplot(sub,aes(x=Param,y=Value,fill=Param))
g<-g+geom_boxplot()
g<-g+facet_wrap(~Species)
g<-g+geom_hline(aes(yintercept=min,colour="Min Sepal Length"),linetype="dashed",show_guide=TRUE)
g<-g+geom_hline(aes(yintercept=max,colour="Max Sepal Length"),linetype="dashed",show_guide=TRUE)
g<-g+theme()+scale_color_manual(values=c("blue","black"))
g<-g+theme(legend.position="bottom")+guides(colour=guide_legend(title=NULL))
g<-g+theme(legend.position="bottom")+guides(fill=guide_legend(title=NULL))
g<-g+theme(legend.box="horizontal")

plot_list[[i]] = g

}

pdf("TEST.pdf",height = 8.5, width = 11,onefile=TRUE,paper="special")
for (i in indices) {
print(plot_list[[i]])
}
dev.off()

这会生成带有漂亮图例的图,但水平线的值都相同。我可以通过ggplot2将我的有限经验与线条美学相映射。如果我没有映射它们并执行此操作,则行值会正确更改,但不会更改图例。

library(dplyr)
library(ggplot2)
library(tidyr)    
liris<-gather(iris,"Param","Value",1:4)
liris<-as.data.frame(liris)

indices<-unique(liris$Param)
plot_list<-list()
for (i in indices) {
sub<-filter(liris,Param==i)

min<-min(sub$Value)
max<-max(sub$Value)

g<-ggplot(sub,aes(x=Param,y=Value,fill=Param))
g<-g+geom_boxplot()
g<-g+facet_wrap(~Species)
g<-g+geom_hline(yintercept=min,colour="black",linetype="dashed",show_guide=TRUE)
g<-g+geom_hline(yintercept=max,colour="blue",linetype="dashed",show_guide=TRUE)
g<-g+theme(legend.position="bottom")+guides(colour=guide_legend(title=NULL))
g<-g+theme(legend.position="bottom")+guides(fill=guide_legend(title=NULL))
g<-g+theme(legend.box="horizontal")

plot_list[[i]] = g

}

pdf("TEST2.pdf",height = 8.5, width = 11,onefile=TRUE,paper="special")
for (i in indices) {
print(plot_list[[i]])
}
dev.off()

任何反馈和想法都会纠正这一点非常受欢迎。非常感谢。

2 个答案:

答案 0 :(得分:3)

我对格式化了一点点,但是这里有一个解决方案,可以为您提供所需的最小值和最大值。请记住,因为geom_boxplot()正在设置xlims(),所以虚线始终构成绘图范围,但是刻度值是波动的。

indices<-unique(liris$Param)
plot_list<-list()
for (i in indices) {
    sub <- filter(liris,Param==i)
    #min <- min(sub$Value)
    #max <- max(sub$Value)

    g <- ggplot(sub,aes(x=Param,y=Value)) +
        geom_boxplot(fill = "green", alpha = .5) +
        facet_wrap(~Species) +
        geom_hline(aes(yintercept=min(Value),colour="Max"),linetype="dashed",show.legend=TRUE) +
        geom_hline(aes(yintercept=max(Value),colour="Min"),linetype="dashed",show.legend=TRUE) + 
        scale_color_manual(values=c("blue","red")) +
        theme_bw() +
        theme(legend.position="bottom")+guides(colour=guide_legend(title=NULL)) +
        theme(legend.position="bottom")+guides(fill=guide_legend(title=NULL)) +
        theme(legend.box="horizontal") +
        labs(title = paste0(i, " Facetted by Species"), x = "", y = "cm")

    plot_list[[i]] <- g
}
pdf("TEST2.pdf",height = 8.5, width = 11,onefile=TRUE,paper="special")
for (i in plot_list) {
    print(i)
}
dev.off()

您真正需要做的就是在各自的geom_hline()内部而不是在构建之前调用min(Value)和max(Value)函数。 aes()中的任何元素都应该来自为情节(liris)提供的数据,而不仅仅是环境中的变量(最小值,最大值)

enter image description here

答案 1 :(得分:3)

这是一个可能的解决方案,它显示了在ggplot2中包含辅助或摘要数据的常用方法。这不是你问题的确切解决方案,但是由@Nathan Day提供。

下面,我创建了第二个包含摘要数据(最小值和最大值)的data.frame。一个关键概念是aes()的目的是在data.frame的和绘图的可视特征之间创建关联。在geom_hline()调用中,我使用aes()StatValue列映射到yintercept功能,SummaryStatistic列与colour相关联功能。请注意,linetype在<{1}}的之外使用,因为我们希望所有8个hlines具有相同的线型,而不管摘要数据列中的任何信息。

aes()

enter image description here