Подтвердить что ты не робот

В сетке `facet_wrap`ed, центральные подсети в 0, сохраняя` free_x`

На следующем графике у меня есть грань сетки.

Есть ли способ центрировать обе подзадачи в 0, сохраняя при этом значения min/max для оси x?

В нижеследующем случае это будет xlim=c(-1,1) для левого и xlim=c(-2,2) для правого, но это должно быть общеприменимо.

(в реальной жизни это граненый сюжеты вулканов, и я хочу сосредоточиться на размере эффекта 0, но сохраняю различные шкалы x для разных графиков)

library(ggplot2)
df = data.frame(x=c(1,2), y=c(0,0), group=c(1,2))
ggplot(df, aes(x=x, y=y)) + geom_point() + facet_wrap(~group, scale="free_x")

введите описание изображения здесь

4b9b3361

Ответ 1

Мне также понадобилось нечто подобное, чтобы отображать асимметричные спектры бок о бок,

введите описание изображения здесь

Попробуйте эту функцию,

symmetrise_scale <- function(p, axis = "x"){
  gb <- ggplot_build(p)
  type <- switch(axis, "x" = "x.range", "y" = "y.range")
  lims <- sapply(gb$panel$ranges, "[[", type)
  fname <- as.character(p$facet$facets)
  facets <- gb$panel$layout[[fname]]
  lims2 <- as.vector(t(tcrossprod(apply(abs(lims), 2, max), c(-1,1))))
  dummy <- setNames(data.frame(rep(facets, each=2), lims2), c(fname, axis))
  switch(axis, 
         "x" = p + geom_blank(data=dummy, aes(x=x, y=Inf), inherit.aes = FALSE), 
         "y" = p + geom_blank(data=dummy, aes(x=Inf, y=y), inherit.aes = FALSE))
}


library(ggplot2)
df = data.frame(x=c(1,2), y=c(5,0.2), group=c(1,2))
p <- ggplot(df, aes(x=x, y=y)) + geom_point() + facet_wrap(~group, scale="free")
symmetrise_scale(p, "x")

введите описание изображения здесь

symmetrise_scale(p, "y")

введите описание изображения здесь

Ответ 2

с версией ggplot2_2.2.1.9000

symmetrise_scale <- function(p, axis = "x"){
  gb <- ggplot_build(p)
  type <- switch(axis, "x" = "x.range", "y" = "y.range")

  fname <- setdiff(names(gb$layout$layout), c("PANEL", "ROW", "COL",  "SCALE_X", "SCALE_Y"))  
  facets <- gb$layout$layout[ ,fname, drop=FALSE]

  lims <- do.call(cbind, lapply(gb$layout$panel_params, "[[", type))
  lims2 <- as.vector(t(tcrossprod(apply(abs(lims), 2, max), c(-1,1))))

  dummy <- setNames(data.frame(facets[rep(seq_len(nrow(facets)), each=2),], lims2), c(fname, axis))

    switch(axis, 
         "x" = p + geom_blank(data=dummy, aes(x=x, y=Inf), inherit.aes = FALSE), 
         "y" = p + geom_blank(data=dummy, aes(x=Inf, y=y), inherit.aes = FALSE))
}

Ответ 3

Более простым, возможно, более надежным решением будет следующее. В более сложном графике с использованием нескольких фреймов данных вам понадобится аналогичный термин geom_blank для каждого из них.

df = data.frame(x=c(1,2,3,4,5,6), y=c(5,-3,2,-0.2,0.3,-0.1), group=c(1,1,1,2,2,2))

ggplot(df, aes(x=x, y=y)) + 
      geom_blank(aes(y=-y)) + #plot mirror image points invisibly (can do same with x)
      geom_line() + facet_wrap(~group, scale="free")

введите описание изображения здесь

Ответ 4

library(ggplot2)
library(tidyverse)

df = data.frame(x=c(1,2), y=c(0,0), group=c(1,2))

# determine the maximum range
df_xr <- df %>% 
  group_by(group) %>%
  summarize(xr = max(abs(x))) %>%
  ungroup()

# join the mximum range ot original df
df_plot <- df %>% 
  inner_join(df_xr)

# plot using geom_blank to force the extents without plotting anything
ggplot(df_plot, aes(x=x, y=y)) + 
  geom_blank(aes(x = xr)) +
  geom_blank(aes(x = -xr)) +
  geom_point() + 
  facet_wrap(~group, scale="free_x")

введите описание изображения здесь

Ответ 5

Это похоже на трюк - на данный момент (это ggplot2 2.2.1). Основные изменения в предыдущем ответе - это отражение изменений в именах/структуре объекта ggplot_build.

symmetrise_scale <- function(p, axis = "x"){
  gb <- ggplot_build(p)
  type <- switch(axis, "x" = "x.range", "y" = "y.range")

  fname <- setdiff(names(gb$layout$panel_layout), c("PANEL", "ROW", "COL",  "SCALE_X", "SCALE_Y"))  
  facets <- gb$layout$panel_layout[ ,fname, drop=FALSE]

  lims <- do.call(cbind, lapply(gb$layout$panel_ranges, "[[", type))
  lims2 <- as.vector(t(tcrossprod(apply(abs(lims), 2, max), c(-1,1))))

  dummy <- setNames(data.frame(facets[rep(seq_len(nrow(facets)), each=2),], lims2), c(fname, axis))

  switch(axis, 
         "x" = p + geom_blank(data=dummy, aes(x=x, y=Inf), inherit.aes = FALSE), 
         "y" = p + geom_blank(data=dummy, aes(x=Inf, y=y), inherit.aes = FALSE))
}


library(ggplot2)
df <- data.frame(x=c(1,2,3,4,5,6), y=c(5,-3,2,-0.2,0.3,-0.1), group=c(1,1,1,2,2,2))
p <- ggplot(df, aes(x=x, y=y)) + geom_line() + facet_wrap(~group, scale="free")
symmetrise_scale(p, "y")

введите описание изображения здесь