这基本上是同一个问题this one,但有一个重要的区别:我想要一个带有水平面板的基于ggplot2的平铺图,并且所有的瓷砖高度相等。另一个问题是垂直面板。
以下是一些示例代码,基于另一个问题中的代码:
d = data.frame(sites=rep(paste("S", 1:31),each=12),
month=factor(rep(1:12,31)),
value=runif(31*12),
panel=c(rep("Group 1",16*12), rep("Group 2", 12*12),
rep("Group 3", 3*12)))
使用
绘制图片ggplot(d, aes(x=month, y=sites, fill=value)) +
geom_tile(colour="white") + facet_wrap(~panel, nrow=1)
结果为
基本上,我希望每块蓝色瓷砖向上移动,以便它们上方没有空间。我可以使用
实现这一目标ggplot(d, aes(x=month, y=sites, fill=value, colour="white")) +
geom_tile(colour="white") + facet_wrap(~panel, scales="free_y", nrow=1)
但这导致高度不等的瓷砖:
The other question有一个很好的垂直面板解决方案,但将此应用于上述代码无效。水平面板有类似的解决方案吗?
答案 0 :(得分:4)
以下是使用gridExtra
并设置级别的黑客攻击:
d.splt <- split(d, d$panel)
max.unique <- max(sapply(d.splt, function(x) length(unique(x$sites))))
d.gg <- lapply(d.splt, function(d.sub){
lvls <- unique(as.character(d.sub$sites))
length(lvls) <- max.unique
lvls <- replace(lvls, is.na(lvls), "")
d.sub$sites <- factor(as.character(d.sub$sites), levels=lvls)
ggplot(d.sub, aes(x=month, y=sites, fill=value, colour="white")) +
geom_tile(colour="white", stat="identity") +
scale_y_discrete(drop=F) + scale_fill_continuous(guide=F)
} )
library(gridExtra)
do.call(grid.arrange, c(d.gg, list(nrow=1)))
这会抛出一些警告,但你可以忽略它们。此外,您还需要添加标题和图例(您可以使用逻辑,以便最后一个生成图例)。
这个问题的主要问题是色标将独立地适合每个图形,但是你可以强制它被修复。
答案 1 :(得分:0)
我会接受@ BrodieG的解决方案,因为这是我的问题的最通用的解决方案,但我会添加我自己的,对于特殊情况,实际的行/站点名称无关紧要,只有(内-panel)tile行的顺序。在这里,我们可以使用hack,我们将所有子组中的级别名称更改为具有最大行数的组中使用的级别名称。示例数据和原始图:
# Example data
set.seed(7)
d = data.frame(sites=rep(paste("S", 1:31),each=12),
month=factor(rep(1:12,31)),
value=runif(31*12),
panel=c(rep("Group 1",16*12),
rep("Group 2", 12*12),
rep("Group 3", 3*12)))
# Reorder rows / site names (just to show that the code works properly)
d$sites = reorder(d$sites, d$value, mean)
# Original plot
library(ggplot2)
ggplot(d, aes(x=month, y=sites, fill=value)) +
geom_tile(colour="white") + facet_wrap(~panel, nrow=1)
现在我们只需要更改每个子组的站点名称:
# Fetch the name of the group with the most rows
library(plyr)
d.stat = ddply(d, .(panel), summarise, nrows=length(unique(sites)))
maxpanel = with(d.stat, panel[which.max(nrows)])
# Fetch the levels / rownames of the group with the most rows
levels.maxpanel = levels(droplevels(subset(d, panel==maxpanel))$sites)
# Substitute the levels / row names of the
# biggest group for each subgroup
subs.levels = function(d.sub) {
levels.subpanel = rev(levels(droplevels(d.sub$sites)))
d.sub$sites[] = rev(levels.maxpanel)[match(d.sub$sites, levels.subpanel)]
d.sub
}
d.recoded = ddply(d, .(panel), subs.levels)
# New plot
ggplot(d.recoded, aes(x=month, y=sites, fill=value)) +
geom_tile(colour="white") + facet_wrap(~panel, nrow=1) +
theme(axis.text.y=element_blank())