我在三个地点收集了数据,其中每个数据都是针对多个主题多次收集的。
以下是数据的外观:
set.seed(1)
df <- data.frame(site = c(rep("AA",1000),rep("BB",500),rep("CC",750)),
y = c(rnorm(1000,1,2),runif(500,1,3),rgamma(750,shape=1)))
#add subjects - using a function that randomly generates
#a number of subjects that adds up to their total at that site
site_a_subjects <- diff(c(0, sort(20*sample(19)), 1000))
site_b_subjects <- diff(c(0, sort(30*sample(9)), 500))
site_c_subjects <- diff(c(0, sort(40*sample(4)), 750))
#add these subjects
df$site_subjects <- c(unlist(sapply(1:20, function(x) rep(letters[x], site_a_subjects[x]))),
unlist(sapply(1:10, function(x) rep(letters[x], site_b_subjects[x]))),
unlist(sapply(1:5, function(x) rep(letters[x], site_c_subjects[x]))))
我想在每个网站上绘制y
的直方图。
这个简单的ggplot2
简单线就可以轻松实现:
ggplot(df, aes(x=y)) + geom_histogram(colour="black", fill="white") + facet_grid(. ~ site)
然而,我还想在每个站点直方图上绘制一个子图,该子图是该站点上每个受试者观察数的计数的直方图。 有点像添加:
hist(table(df$site_subjects[which(df$site == "AA")]))
hist(table(df$site_subjects[which(df$site == "BB")]))
hist(table(df$site_subjects[which(df$site == "CC")]))
分别为三个站点直方图。
知道如何做到这一点?
我想知道是否可以调整annotation_custom
来实现这个目标吗?
此代码可以使用,但仅限于:
ggplotGrob(ggplot(df, aes(x=site_subjects)) + geom_bar() + theme_bw(base_size=9))
命令可以接受list
个ggplot
个对象或类似的东西。
这是'差不多;解: 首先弄清楚所有刻面直方图中的最大条形高度是什么
ymax <- max(sapply(unique(df$site), function(x) max(hist(df$y[which(df$site == x)],plot=FALSE)$counts)))
然后:
main.plot <- ggplot(df, aes(x=y)) + geom_histogram(colour="black", fill="gray") + facet_grid(~site) + scale_y_continuous(limits=c(0,1.2*ymax))
main.plot.info <- ggplot_build(main.plot)
xmin <- min(main.plot.info$data[[1]]$x[which(main.plot.info$data[[1]]$PANEL == 1)])
xmax <- max(main.plot.info$data[[1]]$x[which(main.plot.info$data[[1]]$PANEL == 1)])
main.plot <- main.plot + annotation_custom(grob = grid::roundrectGrob(),xmin = xmin, xmax = xmax, ymin=ymax, ymax=1.2*ymax)
sub.plot <- ggplotGrob(ggplot(df, aes(x=site_subjects)) + geom_bar() + theme_bw(base_size=9))
combined.plot <- main.plot + annotation_custom(grob = sub.plot, xmin = xmin, xmax = xmax, ymin=ymax, ymax=1.2*ymax)
答案 0 :(得分:2)
执行此操作的一种方法是创建主图,然后通过在您想要插入图的每个位置创建视口来添加每个插图。我们使用grid
包中的函数进行这些操作。这是一个例子:
library(grid)
# Function to draw the inset plots
pp = function(var) {
grid.draw(
ggplotGrob(
ggplot(df[df$site==var,], aes(site_subjects)) +
geom_bar() +
theme_bw(base_size=9)
)
)
}
# Function to place the viewports on the main graph
my_vp = function(x) {
viewport(x=x, y=.8, width=0.25, height=0.2)
}
# Main plot
ggplot(df, aes(x=y)) + geom_histogram(colour="black", fill="white") +
facet_grid(. ~ site) +
scale_y_continuous(limits=c(0,400))
# Draw each inset plot in a separate viewport
vp = my_vp(0.22)
pushViewport(vp)
pp("AA")
popViewport()
vp = my_vp(0.52)
pushViewport(vp)
pp("BB")
popViewport()
vp = my_vp(0.84)
pushViewport(vp)
pp("CC")
答案 1 :(得分:0)
这是合理的:
ymax <- max(sapply(unique(df$site), function(x) max(hist(df$y[which(df$site == x)],plot=FALSE)$counts)))
sites <- unique(df$site)
plot.list <- sapply(sites, function(s) {
main.plot = ggplot(df[which(df$site == s),], aes(x=y)) + geom_histogram(colour="black", fill="gray") + scale_y_continuous(limits=c(0,1.5*ymax))
main.plot.info = ggplot_build(main.plot)
xmin = min(main.plot.info$data[[1]]$x[which(main.plot.info$data[[1]]$PANEL == 1)])
xmax = max(main.plot.info$data[[1]]$x[which(main.plot.info$data[[1]]$PANEL == 1)])
sub.plot = ggplotGrob(ggplot(df[which(df$site == s),], aes(x=site_subjects)) + geom_bar() + theme_bw(base_size=9))
return(ggplotGrob(main.plot + annotation_custom(grob = sub.plot, xmin = xmin, xmax = xmax, ymin=0.8*ymax, ymax=1.2*ymax)))})
grid.arrange(grobs=plot.list, ncol=3)