在ggplot中的常见值周围添加矩形

时间:2012-11-30 13:31:41

标签: r ggplot2

当我进行实验设计时,我使用ggplot来显示布局。这是一个简单的例子:

df <- data.frame(Block=rep(1:2, each=18),
            Row=rep(1:9, 4),
            Col=rep(1:4, each=9),
            Treat=sample(c(1:6),replace=F))

我的情节如下:

df.p <- ggplot(df, aes(Row, Col)) + geom_tile(aes(fill=as.factor(Treat)))

给予:

design

有时我在设计中有一个结构我希望通过在它周围放一个框来突出显示,例如主图。在这种情况下:

df$Mainplot <- ceiling(df$Row/3) + 3*(ceiling(df$Col/2) - 1)

然后我使用geom_rect和一些需要调整每个设计的杂乱代码来生成类似的东西:

designwithmainplot

问题:如何以简单的方式在主图周围添加矩形?这似乎是一个简单的问题,但我还没有找到一个明显的方法。我可以将颜色或其他美学映射到主图,但我似乎无法用一个盒子包围它们。任何指针都非常感激。

3 个答案:

答案 0 :(得分:5)

这是一个可能的解决方案,我在其中创建一个辅助data.frame,用于绘制带geom_rect()的边框。我不确定这是否像你想的那么简单!我希望计算矩形坐标的代码可以重复使用/推广,只需要额外的努力。

library(ggplot2)

# Load example data.
df = data.frame(Block=rep(1:2, each=18),
            Row=rep(1:9, 4),
            Col=rep(1:4, each=9),
            Treat=sample(c(1:6),replace=F))
df$Mainplot = ceiling(df$Row/3) + 3*(ceiling(df$Col/2) - 1)

# Create an auxiliary data.frame for plotting borders.
group_dat = data.frame(Mainplot=sort(unique(df$Mainplot)),
                       xmin=0, xmax=0, ymin=0, ymax=0)
# Fill data.frame with appropriate values.
for(i in 1:nrow(group_dat)) {
    item = group_dat$Mainplot[i]
    tmp = df[df$Mainplot == item, ]
    group_dat[i, "xmin"] = min(tmp$Row) - 0.5
    group_dat[i, "xmax"] = max(tmp$Row) + 0.5
    group_dat[i, "ymin"] = min(tmp$Col) - 0.5
    group_dat[i, "ymax"] = max(tmp$Col) + 0.5
}


p2 = ggplot() + 
     geom_tile(data=df, aes(x=Row, y=Col, fill=factor(Treat)), 
               colour="grey30", size=0.35) +
     geom_rect(data=group_dat, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
               size=1.4, colour="grey30", fill=NA)

ggsave(filename="plot_2.png", plot=p2, height=3, width=6.5) 

enter image description here

答案 1 :(得分:2)

这是一个可能更容易的解决方案。只需使用geom_tile并将alpha设置为0.我没有花时间给你一个确切的解决方案,但这是一个例子。要实现你想要的,我猜你需要实际创建一个新的数据框,这应该很容易。

df <- data.frame(Block=rep(1:2, each=18),Row=rep(1:9, 4),Col=rep(1:4, each=9),Treat=sample(c(1:6),replace=F))
df$blocking <- rep(sort(rep(1:3,3)),4)
df.p <- ggplot(df, aes(Row, Col)) + geom_tile(aes(fill=as.factor(Treat)))
df.p+ geom_tile(data=df,aes(x=Row,y=blocking),colour="black",fill="white",alpha=0,lwd=1.4)

alpha=0将创建一个空白图块,然后您可以使用lwd设置线宽。这可能比指定所有矩形更容易。希望它有所帮助。

答案 2 :(得分:0)

我认为值得发布我自己的(非理想的)解决方案,因为似乎没有什么明显的我错过了。我要留下未回答的问题,希望有人会提出一些建议。

目前,我使用geom_rect的方式可能是一般的(也许是ggplot的geom_border添加?)。对于我的问题中的示例,基本信息是每个主图是3 x 2.

从原始问题添加到df.p,这就是我目前所做的事情:

df.p1 <- df.p + geom_rect(aes(xmin=((Mainplot- 3*(ceiling(Col/2)-1) )-1)*3 + 0.5,
                         xmax=((Mainplot - 3*(ceiling(Col/2)-1))-1)*3 + 3.5,
                         ymin=ceiling(ceiling(Col/2)/2 + 2*(ceiling(Col/2)-1))-0.5,
                         ymax=2*ceiling(Col/2)+0.5),
                     colour="black", fill="transparent",size=1)

丑陋,我知道 - 因此这个问题。该代码从问题中生成第二个图。也许最好的选择就是把这一切都融入到一个功能中。