3

我想facet_zoom()用来放大明确设置了限制的轴的一部分。但是,使用scale_*(limits = *)coord_cartesian(xlim = *)覆盖缩放的刻面的比例,以使两者具有相同的限制。有没有解决的办法?也许我可以在限制附近添加一些数据点,然后设置它们alpha = 0......还有其他想法吗?

library(ggplot2)
library(ggforce)
# works with no limits specified
ggplot(mpg, aes(x = hwy, y = cyl)) + 
  geom_point() +
  facet_zoom(xlim = c(20, 25))

成功案例

# fails with limits specified
ggplot(mpg, aes(x = hwy, y = cyl)) + 
  scale_x_continuous(limits = c(0, 50)) +
  geom_point() +
  facet_zoom(xlim = c(20, 25))

失败案例1

# fails with coord_cartesian()
ggplot(mpg, aes(x = hwy, y = cyl)) + 
  scale_x_continuous() +
  coord_cartesian(xlim = c(0, 50)) +
  geom_point() +
  facet_zoom(xlim = c(20, 25))

失败案例2

4

1 回答 1

2

我对 中的潜在复杂性没有足够的了解FacetZoom,但您可以检查以下解决方法是否提供了一个合理的起点。

演示图

在此处输入图像描述

scales_*设置限制与设置限制之间的主要区别之一是剪辑效果(屏幕截图取自此处coord_*的 ggplot2 备忘单)。由于这种效果在散点图中并不是很清楚,因此我添加了一个图层并调整了指定的限制,以便限制超出 x 轴一端的数据范围,并在另一端剪辑数据。geom_line

p <- ggplot(mpg, aes(x = hwy, y = cyl)) +
  geom_point() +
  geom_line(aes(colour = fl), size = 2) +
  facet_zoom(xlim = c(20, 25)) +
  theme_bw()

# normal zoomed plot / zoomed plot with limits set in scale / coord
p0 <- p
p1 <- p + scale_x_continuous(limits = c(0, 35))
p2 <- p + coord_cartesian(xlim = c(0, 35))

演示图

我们可以看到,虽然 p0 的行为符合预期,但 p1 和 p2 都显示了具有相同范围的原始 facet(顶部)和缩放的 facet(底部)c(0, 35)

在 p1 的情况下,阴影框也扩大到覆盖整个顶面。在 p2 的情况下,缩放框与 p0 保持在完全相同的位置,因此不再覆盖c(20, 25).

中设置的限制的解决方法scale_*

# convert ggplot objects to form suitable for rendering
gp0 <- ggplot_build(p0)
gp1 <- ggplot_build(p1)

# re-set zoomed facet's limits to match zoomed range
k <- gp1$layout$layout$SCALE_X[gp1$layout$layout$name == "x"]
gp1$layout$panel_scales_x[[k]]$limits <- gp1$layout$panel_scales_x[[k]]$range$range 

# re-set zoomed facet's panel parameters based on original version p0
k <- gp1$layout$layout$PANEL[gp1$layout$layout$name == "x"]
gp1$layout$panel_params[[k]] <- gp0$layout$panel_params[[k]]

# convert built ggplot object to gtable of grobs as usual & print result
gt1 <- ggplot_gtable(gp1)
grid::grid.draw(gt1)

具有按比例设置的限制的绘图

缩放面现在c(20, 25)正确显示缩放范围,而阴影框缩小以覆盖原始面中的正确范围。由于此方法删除了看不见的数据点,因此原始 facet 中的所有线都保留facet的范围内。

中设置的限制的解决方法coord_*

# convert ggplot objects to form suitable for rendering
gp0 <- ggplot_build(p0)
gp1 <- ggplot_build(p1)

# apply coord limits to original facet's scale limits
k <- gp2$layout$layout$SCALE_X[gp2$layout$layout$name == "orig"]
gp2$layout$panel_scales_x[[k]]$limits <- gp2$layout$coord$limits$x

# re-set zoomed facet's panel parameters based on original version without setting
# limits in scale
k <- gp1$layout$layout$PANEL[gp1$layout$layout$name == "x"]
gp2$layout$panel_params[[k]] <- gp0$layout$panel_params[[k]]

# convert built ggplot object to gtable of grobs as usual,
# & print result
gt2 <- ggplot_gtable(gp2)
grid::grid.draw(gt2)

具有坐标限制的绘图

缩放的分面现在可以正确显示缩放范围c(20, 25),而阴影框会移动以覆盖原始分面中的正确范围。由于此方法包括看不见的数据点,原始构面中的一些线超出了构面的范围。

注意:这些解决方法也适用于在 y 轴上设置的 y + 限制,只要所有对"x"/ panel_scales_x/SCALE_X以上的引用都更改为"y"/ panel_scales_y/ SCALE_Y。我还没有对其他组合进行测试,例如放大 x 和 y,但大体原理应该是相似的。

于 2019-10-07T16:33:04.910 回答