使用 gridExtra 和 annotation_custom() 将 table 添加到 ggplot 会更改 y 轴限制
Adding a table to ggplot with gridExtra and annotation_custom() changes y-axis limits
我尝试在我用 ggplot2::ggplot()
创建的情节中添加一些摘要 table。 table 通过 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)
编辑:
我刚刚发现这似乎是 stat_summary()
的问题。当我使用另一个 geom/layer 时,限制将保持在原始图中。另一个例子:
plot2 = ggplot(data = ChickWeight, aes(x = Time, y = weight, color = Diet)) +
geom_jitter()
plot2
plot2 + annotation_custom(sum_table)
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
顺便说一下,这两个图不会给出完全相同的 y 范围的原因是 stat_summary()
中的 bootstrap 函数。实际上,重复绘制 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 样本。
我尝试在我用 ggplot2::ggplot()
创建的情节中添加一些摘要 table。 table 通过 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)
编辑:
我刚刚发现这似乎是 stat_summary()
的问题。当我使用另一个 geom/layer 时,限制将保持在原始图中。另一个例子:
plot2 = ggplot(data = ChickWeight, aes(x = Time, y = weight, color = Diet)) +
geom_jitter()
plot2
plot2 + annotation_custom(sum_table)
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
顺便说一下,这两个图不会给出完全相同的 y 范围的原因是 stat_summary()
中的 bootstrap 函数。实际上,重复绘制 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 样本。