5 votes

Ggplot2 modifier les limites des axes pour chaque panneau de facettes individuel

library(tidyverse)
ggplot(mpg, aes(displ, cty)) + 
  geom_point() + 
  facet_grid(rows = vars(drv), scales = "free")

Le code ggplot ci-dessus se compose de trois panneaux 4, f et r. Je voudrais que les limites de l'axe y soient les suivantes pour chaque panneau :

Panel y-min y-max breaks
----- ----- ----- ------
4     5     25    5
f     0     40    10
r     10    20    2

Comment modifier mon code pour réaliser cela ? Je ne sais pas si scale_y_continuous est plus approprié ou coord_cartesian, ou une combinaison des deux.

6voto

Ben Bolker Points 50041

Préliminaires

Définir le tracé original et les paramètres souhaités pour les axes Y de chaque facette:

library(ggplot2)
g0 <- ggplot(mpg, aes(displ, cty)) + 
    geom_point() + 
    facet_grid(rows = vars(drv), scales = "free")

facet_bounds <- read.table(header=TRUE,
text=                           
"drv ymin ymax breaks
4     5     25    5
f     0     40    10
r     10    20    2",
stringsAsFactors=FALSE)

version 1: mettre des points de données fictifs

Cela ne respecte pas la spécification des breaks, mais cela obtient les limites correctes:

Définir un nouveau data frame qui inclut les valeurs min/max pour chaque drv:

ff <- with(facet_bounds,
           data.frame(cty=c(ymin,ymax),
                      drv=c(drv,drv)))

Ajoutez-les aux tracés (ils ne seront pas tracés car x est NA, mais ils sont toujours utilisés pour définir les échelles)

g0 + geom_point(data=ff,x=NA)

C'est similaire à ce que fait expand_limits(), sauf que cette fonction s'applique "pour tous les panneaux ou tous les tracés".

version 2: détecter dans quel panneau vous vous trouvez

Ceci est laid et dépend du fait que chaque groupe a une plage unique.

library(dplyr)
## calculer les limites pour chaque groupe
lims <- (mpg
    %>% group_by(drv)
    %>% summarise(ymin=min(cty),ymax=max(cty))
)

Fonction des ruptures: détermine quel groupe correspond à l'ensemble de limites qui lui est donné ...

bfun <- function(limits) {
    grp <- which(lims$ymin==limits[1] & lims$ymax==limits[2])
    bb <- facet_bounds[grp,]
    pp <- pretty(c(bb$ymin,bb$ymax),n=bb$breaks)
    return(pp)
}
g0 + scale_y_continuous(breaks=bfun, expand=expand_scale(0,0))

L'autre laideur ici est que nous devons définir expand_scale(0,0) pour que les limites soient exactement égales aux limites du groupe, ce qui pourrait ne pas être la façon dont vous voulez le tracé ...

Il serait bien si la fonction breaks() pouvait somehow également recevoir des informations sur le panneau actuellement en cours de calcul ...

5voto

Uwe Points 21553

Il s'agit d'une demande de fonctionnalité de longue date (voir, par exemple, 2009, 2011, 2016) qui est abordée par un package distinct facetscales.

devtools::install_github("zeehio/facetscales")
library(g)
library(facetscales)
scales_y <- list(
  `4` = scale_y_continuous(limits = c(5, 25), breaks = seq(5, 25, 5)),
  `f` = scale_y_continuous(limits = c(0, 40), breaks = seq(0, 40, 10)),
  `r` = scale_y_continuous(limits = c(10, 20), breaks = seq(10, 20, 2))
)
ggplot(mpg, aes(displ, cty)) + 
  geom_point() + 
  facet_grid_sc(rows = vars(drv), scales = list(y = scales_y))

description de l'image

Si les paramètres de chaque facette sont stockés dans un dataframe facet_params, nous pouvons calculer en langage pour créer scale_y:

library(tidyverse)
facet_params <- read_table("drv y_min y_max breaks
4     5     25    5
f     0     40    10
r     10    20    2")

scales_y <- facet_params %>% 
  str_glue_data(
    "`{drv}` = scale_y_continuous(limits = c({y_min}, {y_max}), ", 
                "breaks = seq({y_min}, {y_max}, {breaks}))") %>%
  str_flatten(", ") %>% 
  str_c("list(", ., ")") %>% 
  parse(text = .) %>% 
  eval()

3voto

Johanna Points 31

Je voulais utiliser une échelle logarithmique avec les facettes et j'ai eu du mal.

Il s'est avéré que je dois spécifier le log10 à deux positions :

scales_x <- list(
  "B" = scale_x_log10(limits=c(0.1, 10), breaks=c(0.1, 1, 10)),
  "C" = scale_x_log10(limits=c(0.008, 1), breaks=c(0.01, 0.1, 1)),
  "E" = scale_x_log10(limits=c(0.01, 1), breaks=c(0.01, 0.1, 1)),
  "R" = scale_x_log10(limits=c(0.01, 1), breaks=c(0.01, 0.1, 1))
)

et dans le graphique

ggplot(...) + facet_grid_sc(...) +  scale_x_log10()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X