13

考虑一些facet_grid情节

mt <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() 
mt + facet_grid(vs ~ am, scales = "free") 

绘图

想象一下,我只想放大上面图中的第一行,只显示 3 到 4 之间的 y 轴值。coord_cartesian()如果它们没有刻面或者我想放大所有图,我可以这样做,但是在这种情况下没有一个好的解决方案。我想我可以先对数据进行子集化,但这是有充分理由的禁忌(例如,会抛弃任何统计层等)。

(请注意,问题与此相关:R:{ggplot2}:如何/我可以独立调整 facet_grid 图上的 x 轴限制?但那里的答案不适用于此目的。)

4

3 回答 3

12

所以,这是一个老问题,但我想分享一种我发现的方法。最简单的似乎是在您的数据中添加人工点,例如在每个图的数据的左下角和右上角。将此信息放入单独的数据框中,然后使用参数 alpha=0 将其添加到带有 geom_point 的绘图中,以使点不可见。根据您的需要,将 facet_wrap 中的轴缩放设置为“free_x”或“free_y”。

现在 ggplot 分别缩放每个方面以适应您添加的不可见点。有点hacky,但效果很好。

于 2015-05-25T11:55:29.143 回答
9

旧帖子,但我一直在寻找相同的东西,但实际上找不到任何东西 - [也许这是一种使用 facet_grid() 为两个因变量设置 y 轴限制的方法

该解决方案不是很优雅/高效,但我认为它有效 - 基本上创建两个具有不同 coord_cartesian 调用的图并交换 grobs。

# library(ggplot2)
# library(gtable)

# Plot
mt <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() 

# --------------------------------------------------------------------------------


p1 <- mt + facet_grid(vs ~ am, scales = "free") + coord_cartesian(ylim = c(1,6))
g1 <- ggplotGrob(p1)

p2 <- mt + facet_grid(vs ~ am, scales = "free") + coord_cartesian(ylim = c(3,5))
g2 <- ggplotGrob(p2)

# ----------------------------------------------------------
# Replace the upper panels and upper axis of p1 with that of p2
# Tweak panels of second plot - the upper panels
g1[["grobs"]][[6]] <- g2[["grobs"]][[6]]
g1[["grobs"]][[8]] <- g2[["grobs"]][[8]]

#Tweak axis
g1[["grobs"]][[4]] <- g2[["grobs"]][[4]]

grid.newpage()
grid.draw(g1)
于 2014-03-31T22:56:01.307 回答
0

我提出的解决方案基于@user20650提供的答案。它的不同之处在于使用半自动过程来查找 grobg1中需要替换为g2.

# library(ggplot2)
# library(grid)

p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + 
  geom_point() +
  facet_grid(vs ~ am)

# modify p1 by zooming as desired
p2 <- p1 + coord_cartesian(ylim = c(3,4)) + 
  theme_bw() + 
  theme(axis.text  = element_text(color="blue"),
        strip.text = element_text(color="blue"))

p1
p2

现在我们修改顶面行的 y 轴限制。我们生成两个 grobs g1,并用来自 的相应元素g2替换面板和 y 轴。g1g2

下面的代码根据元素的名称查找要替换的 grob 元素的索引。

g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)

# Replace the upper panels and upper axis of p1 with that of p2
# i.e. replace the corresponding grobs in g1 with the versions of g2
# Panel numbering goes row-wise from top left to bottom right
panels_to_replace_with_g2 <- c(1,2)

# To get names of grobs run: lapply(g1[["grobs"]],function(x) x$name)
# Use names of grobs to find out indices of g1[["grobs"]] of the panels we want to replace
# as well as for the axis ticks.
pattern_for_specific_panels <- 
  paste0("^panel-((",paste0(panels_to_replace_with_g2, collapse = ")|("),"))")
pattern_for_axes_ticks <- 
  "^GRID.absoluteGrob"

idx_panels_to_replace_from_g2 <- which(unlist(
  lapply(g1[["grobs"]], function(x) grepl(pattern_for_specific_panels, x$name))))
# > idx_panels_to_replace_from_g2
# [1] 2 4

idx_axesTicks <- which(unlist(
  lapply(g1[["grobs"]], function(x) grepl(pattern_for_axes_ticks, x$name))))

# Find out manually which of the defined axesTicks it is:
g_test <- g1
for (itr in idx_axesTicks) {
  g_test[["grobs"]][[itr]] <- g2[["grobs"]][[itr]]
  grid.newpage();grid.draw(g_test); grid.draw(textGrob(itr, just = "top"))
  Sys.sleep(1)
}
# We found out it is itr=10
idx_axesTicks_to_replace <- 10

现在已经找到要替换的面板idx_panels_to_replace_from_g2的索引以及 y 轴元素的索引idx_axesTicks_to_replace。我们可以在下面替换它们。

# Replace panels
grid.newpage();grid.draw(g1)
for (iter in idx_panels_to_replace_from_g2) {
  g1[["grobs"]][[iter]] <- g2[["grobs"]][[iter]]
  grid.newpage();grid.draw(g1)
  Sys.sleep(1)
}

# Replace y-axis
g1[["grobs"]][[idx_axesTicks_to_replace]] <- g2[["grobs"]][[idx_axesTicks_to_replace]]

# Render plot
grid.newpage()
grid.draw(g1)

如果绘图成功修改,您现在可以删除我们应用于 p2 的主题修改和文本颜色,以使更改更好地可见。

修改后的情节

未来TODO:现在缺少的是增加y轴的宽度以尊重修改后的轴标签

于 2018-08-27T06:36:48.123 回答