facet_zoom () при установке ограничений оси - PullRequest
3 голосов
/ 07 октября 2019

Я хотел бы использовать 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 Ответ

2 голосов
/ 07 октября 2019

У меня недостаточно знаний о базовых сложностях в FacetZoom, но вы можете проверить, обеспечивают ли следующие обходные пути разумную отправную точку.

Сюжет для демонстрации

enter image description here

Одним из ключевых отличий между установочными пределами в scales_* по сравнению с coord_* является эффект отсечения (снимок экрана взят из таблицы 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, но общий принцип должен быть похожим.

...