设置轴限制时,facet_zoom()

时间:2019-10-06 22:50:17

标签: r ggplot2 ggforce

我想使用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))

success case

# 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))

failure case 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))

failure case 2

1 个答案:

答案 0 :(得分:2)

我对FacetZoom中的底层复杂性没有足够的了解,但是您可以检查以下变通办法是否提供了合理的起点。

演示图

enter image description here

scales_*coord_*中的设置限制之间的主要区别之一是剪辑效果(截取自here的ggplot2备忘单的屏幕截图)。由于在散点图中这种效果还不是很明显,因此我添加了geom_line层并调整了指定的限制,以使限制扩展到x轴一端的数据范围之外,并在另一端。

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))

demo plots

我们可以看到,虽然p0的行为符合预期,但p1和p2都显示了具有相同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)

plot with limits set in scale

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

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)

plot with limits set in coord

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

注意:这些变通办法也应适用于y +在y轴上设置的限制,只要上面所有对"x" / panel_scales_x / SCALE_X的引用更改为"y" / panel_scales_y / SCALE_Y。我还没有针对其他组合(例如x和y的缩放)进行测试,但是广泛的原理应该相似。