web-dev-qa-db-fra.com

Existe-t-il un moyen de manipuler des pauses et des étiquettes GGPLOT?

ggplot Généralement un bon travail de création de pauses et d'étiquettes sensibles dans les écailles.

Cependant, je trouve que dans le terrain avec de nombreuses facettes et peut-être un formatter= Déclaration, les étiquettes ont tendance à devenir trop "dense" et surimpression, par exemple dans cette image:

df <- data.frame(
        fac=rep(LETTERS[1:10], 100),
        x=rnorm(1000)
)

ggplot(df, aes(x=x)) + 
  geom_bar(binwidth=0.5) + 
  facet_grid(~fac) + 
  scale_x_continuous(formatter="percent")

enter image description here

Je sais que je peux spécifier explicitement les pauses et les étiquettes des échelles, en fournissant breaks= et scale= arguments à scale_x_continuous.

Cependant, je traite des données d'enquête avec de nombreuses questions et une douzaine de crosses, afin de trouver un moyen de le faire automatiquement.

Existe-t-il une façon de dire ggplot pour calculer automatiquement les pauses et les étiquettes, mais il suffit d'avoir moins, dites au minimum, maximum et zéro point?

éditer : Idéalement, je ne veux pas spécifier les points minimum et maximum, mais appuyez d'une manière ou d'une autre, appuyez sur la formation de balances GGPLOT intégrée et utilisez les limites d'échelle calculées par défaut.

30
Andrie

Vous pouvez transmettre des arguments tels que min() et max() Dans votre appel à GGPLOT pour spécifier dynamiquement les pauses. On dirait que vous allez appliquer cela sur une grande variété de données afin que vous puissiez envisager d'envisager de généraliser cela dans une fonction et de jouer avec le formatage, mais cette approche devrait fonctionner:

ggplot(df, aes(x=x)) + 
  geom_bar(binwidth=0.5) + 
  facet_grid(~fac) + 
  scale_x_continuous(breaks = c(min(df$x), 0, max(df$x))
    , labels = c(paste( 100 * round(min(df$x),2), "%", sep = ""), paste(0, "%", sep = ""), paste( 100 * round(max(df$x),2), "%", sep = ""))
    )

ou faire pivoter le texte de l'axe des x avec opts(axis.text.x = theme_text(angle = 90, hjust = 0)) pour produire quelque chose comme:

enter image description here

Mise à jour

Dans la dernière version de GGPLot2 le breaks et labels arguments à scale_x_continuous Acceptez les fonctions, donc on peut faire quelque chose comme ce qui suit:

myBreaks <- function(x){
    breaks <- c(min(x),median(x),max(x))
    names(breaks) <- attr(breaks,"labels")
    breaks
}

ggplot(df, aes(x=x)) + 
  geom_bar(binwidth=0.5) + 
  facet_grid(~fac) + 
  scale_x_continuous(breaks = myBreaks,labels = percent_format()) + 
  opts(axis.text.x = theme_text(angle = 90, hjust = 1,size = 5))
26
Chase

Le paquet scales contient plusieurs breaks_* et label_* Fonctions qui renvoient des fonctions (fermetures) utilisées par GGPLOT. Vous pouvez donc écrire un wrappers pour ceux-ci qui modifient la sortie.

Par exemple:

library(ggplot2)

# Compute the list of breaks using original_func,
# then remove any of these that occur in remove_list
remove_breaks <- function(original_func, remove_list = list()) {
  function(x) {
    original_result <- original_func(x)
    original_result[!(original_result %in% remove_list)]
  }
}

# Compute the list of labels using original_func,
# then remove any of these that occur in remove_list
remove_labels <- function(original_func, remove_list = list()) {
  function(x) {
    original_result <- original_func(x)
    replace(original_result, original_result %in% remove_list, '')
  }
}

# Original plot
ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
  scale_x_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = scales::label_number_auto()) +
  scale_y_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = scales::label_number_auto())

# Remove some breaks from the x-axis, and remove some labels from the y-axis
ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
  scale_x_continuous(breaks       = remove_breaks(scales::breaks_pretty(9), seq(3,6)),
                     minor_breaks = remove_breaks(scales::breaks_pretty(18), seq(3,6,0.5)),
                     labels       = scales::label_number_auto()) +
  scale_y_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = remove_labels(scales::label_number_auto(), seq(20, 30)))

Bien sûr, avec mon simple remove_breaks et remove_labels Fonctions Vous devez toujours spécifier quelles valeurs à supprimer, mais vous pouvez facilement les modifier à quelque chose qui supprime la valeur max et min, supprime toute valeur dans une plage spécifiée, etc.

0
Tim Goodman