使用gridExtra和annotation_custom()向ggplot添加表会更改y轴限制

时间:2016-01-13 15:43:46

标签: r ggplot2 gridextra

我尝试在我用ggplot2::ggplot()创建的情节中添加一个小摘要表。该表通过gridExtra::tableGrob()添加到已保存的ggplot对象。

我的问题是,这似乎改变了原始情节的y限制。 有没有办法避免这种情况,而无需通过ylim()再次指定限制?

以下是使用ChickWeight数据集的问题的最小示例:

# load packages
require(ggplot2)
require(gridExtra)

# create plot
plot1 = ggplot(data = ChickWeight, aes(x = Time, y = weight, color = Diet)) +
        stat_summary(fun.data = "mean_cl_boot", size = 1, alpha = .5) 
plot1
# create table to add to the plot
sum_table = aggregate(ChickWeight$weight, 
                      by=list(ChickWeight$Diet), 
                      FUN = mean)
names(sum_table) = c('Diet', 'Mean')
sum_table = tableGrob(sum_table)

# insert table into plot
plot1 + annotation_custom(sum_table)

ylim problem with annotation_custom()

修改 我只是发现它似乎是stat_summary()的一个问题。当我使用另一个geom / layer时,限制将保持原始图中的限制。另一个例子:

plot2 = ggplot(data = ChickWeight, aes(x = Time, y = weight, color = Diet)) +
        geom_jitter() 
plot2
plot2 + annotation_custom(sum_table)

ylim problem with annotation_custom()

1 个答案:

答案 0 :(得分:4)

plot1的y范围与plot2不同,原因是annotation_custom从原始aes语句中获取其美学,而不是stat_summary()使用的修改数据框。要使两个图的y范围相同(或大致相同 - 见下文),请停止annotation_custom从原始数据中获取其美学效果。也就是说,在aes()内移动stat_summary()

# load packages
require(ggplot2)
require(gridExtra)

# create plot
plot1 = ggplot(data = ChickWeight) +
        stat_summary(aes(x = Time, y = weight, color = Diet), fun.data = "mean_cl_boot", size = 1, alpha = .5) 
plot1

# create table to add to the plot
sum_table = aggregate(ChickWeight$weight, 
                      by=list(ChickWeight$Diet), 
                      FUN = mean)
names(sum_table) = c('Diet', 'Mean')
sum_table = tableGrob(sum_table)

# insert table into plot
plot2 = plot1 + annotation_custom(sum_table, xmin = 10, xmax = 10, ymin = 200, ymax = 200) 
plot2

enter image description here

顺便说一下,两个图不会给出完全相同的y范围的原因是因为stat_summary()中的引导函数。实际上,重复绘制p1,您可能会注意到y范围的微小变化。或者检查构建数据中的y范围。

修改更新至ggplot2 ver 3.0.0

ggplot_build(plot1)$layout$panel_params[[1]]$y.range
ggplot_build(plot2)$layout$panel_params[[1]]$y.range

回想一下,ggplot在绘制时间之前不会计算函数 - 每次绘制p1或p2时,都会选择一个新的bootstrap样本。