Comment changer le formatage des nombres sur un axe avec ggplot?

131

J'utilise R et ggplot pour dessiner un nuage de points de certaines données, tout va bien sauf que les nombres sur l'axe y sortent avec un formatage d'exposant de style informatique, c'est-à-dire 4e + 05, 5e + 05, etc. C'est évidemment inacceptable, alors je veux que cela affiche 500 000, 400 000 et ainsi de suite. Obtenir une notation d'exposant appropriée serait également acceptable.

Le code du tracé est le suivant:

p <- ggplot(valids, aes(x=Test, y=Values)) +
  geom_point(position="jitter") +
  facet_grid(. ~ Facet) +
  scale_y_continuous(name="Fluorescent intensity/arbitrary units") +
  scale_x_discrete(name="Test repeat") +
  stat_summary(fun.ymin=median, fun.ymax=median, fun.y=median, geom="crossbar")

Toute aide très appréciée.

Jack Aidley
la source
30
Veillez à ne pas décrire les ggplotoptions par défaut comme «manifestement inacceptables». Vous voulez dire que vous avez une préférence personnelle pour un format différent. Un nombre dans le format 4e+05est une notation scientifique et serait le formatage préféré dans une grande variété d'applications.
Andrie
53
4e + 05 n'est pas une notation scientifique, c'est une approximation informatique de la notation scientifique. Cela ne serait acceptable dans aucun journal imprimé auquel je puisse penser, je le considère donc inacceptable pour ma thèse.
Jack Aidley

Réponses:

126

Une autre option consiste à mettre en forme vos étiquettes de graduation d'axe avec des virgules en utilisant le package scaleset en ajoutant

 scale_y_continuous(name="Fluorescent intensity/arbitrary units", labels = comma)

à votre instruction ggplot.

Si vous ne souhaitez pas charger le package, utilisez:

scale_y_continuous(name="Fluorescent intensity/arbitrary units", labels = scales::comma)
Jim M.
la source
9
Étonnant qu'un problème aussi trivial nécessite de charger un nouveau paquet.
luchonacho
Pour info, cela fonctionne également avec scale_y_log10 (labels = scale :: comma), et je suppose d'autres échelles dans ggplot2. Bons conseils!
TheProletariat
66

J'ai également trouvé une autre façon de faire cela qui donne une notation appropriée 'x10 (exposant) 5' sur les axes. Je le publie ici dans l'espoir qu'il pourrait être utile à certains. J'ai obtenu le code d' ici, donc je n'en revendique aucun crédit, cela revient à juste titre à Brian Diggs.

fancy_scientific <- function(l) {
     # turn in to character string in scientific notation
     l <- format(l, scientific = TRUE)
     # quote the part before the exponent to keep all the digits
     l <- gsub("^(.*)e", "'\\1'e", l)
     # turn the 'e+' into plotmath format
     l <- gsub("e", "%*%10^", l)
     # return this as an expression
     parse(text=l)
}

Que vous pouvez ensuite utiliser comme

ggplot(data=df, aes(x=x, y=y)) +
   geom_point() +
   scale_y_continuous(labels=fancy_scientific) 
Jack Aidley
la source
10
Si vous ne voulez pas que 0 soit imprimé sous la forme "0 x 10⁺⁰", ajoutez ce qui suit sous la format(...)ligne:l <- gsub("0e\\+00","0",l)
semi-extrinsèque
1
Si vous souhaitez ajouter d'autres choses à un cas particulier, il est plus facile d'en ajouter plus gsub()directement après le format(), tout en testant ce qui format()revient pour votre cas dans une console séparée.
semi-extrinsèque du
3
ajoutez ceci avant la dernière gsubcommande: # remove + after exponent, if exists. E.g.: (3x10^+2 -> 3x10^2) l <- gsub("e\\+","e",l)et après: # convert 1x10^ or 1.000x10^ -> 10^ l <- gsub("\\'1[\\.0]*\\'\\%\\*\\%", "", l)pour le rendre au format habituellement utilisé dans les papiers.
John_West
44
x <- rnorm(10) * 100000
y <- seq(0, 1, length = 10)
p <- qplot(x, y)
library(scales)
p + scale_x_continuous(labels = comma)
DiscretCercle
la source
Lorsque j'essaye cela, j'obtiens une erreur indiquant que le formateur est un argument inutilisé? A-t-il besoin d'un autre package ou de quelque chose?
Jack Aidley
4
J'ai changé le code pour inclure library(scales)et utiliser commace qui devrait mieux fonctionner que la fonction que j'avais auparavant.
DiscreteCircle
16

Je suis en retard au jeu ici mais au cas où d'autres voudraient une solution simple, j'ai créé un ensemble de fonctions qui peuvent être appelées comme:

 ggplot + scale_x_continuous(labels = human_gbp)

qui vous donnent des nombres lisibles par l'homme pour les axes x ou y (ou n'importe quel nombre en général vraiment).

Vous pouvez trouver les fonctions ici: Github Repo Copiez simplement les fonctions dans votre script pour pouvoir les appeler.

Feargal Ryan
la source
10

Je trouve la réponse suggérée par Jack Aidley utile.

Je voulais jeter une autre option. Supposons que vous ayez une série avec de nombreux petits nombres et que vous vouliez vous assurer que les étiquettes des axes écrivent le point décimal complet (par exemple 5e-05 -> 0,0005), puis:

NotFancy <- function(l) {
 l <- format(l, scientific = FALSE)
 parse(text=l)
}

ggplot(data = data.frame(x = 1:100, 
                         y = seq(from=0.00005,to = 0.0000000000001,length.out=100) + runif(n=100,-0.0000005,0.0000005)), 
       aes(x=x, y=y)) +
     geom_point() +
     scale_y_continuous(labels=NotFancy) 
EconomiCurtis
la source
23
Cela peut être raccourci en utilisant une fonction anonyme: scale_y_continuous(labels=function(n){format(n, scientific = FALSE)})pourquoi il n'y a pas de formateur prédéfini comme ça, l'enfer sait.
eMPee584