web-dev-qa-db-fra.com

Transformez un seul axe en échelle log10 avec ggplot2

J'ai le problème suivant: je voudrais visualiser une variable discrète et continue sur un boxplot dans lequel ce dernier a quelques valeurs extrêmement élevées. Cela rend le boxplot vide de sens (les points et même le "corps" du graphique est trop petit), c'est pourquoi je voudrais le montrer sur une échelle log10. Je suis conscient que je pourrais laisser de côté les valeurs extrêmes de la visualisation, mais je n'y suis pas destiné.

Voyons un exemple simple avec des données de diamants:

m <- ggplot(diamonds, aes(y = price, x = color))

alt text

Le problème n'est pas grave ici, mais j'espère que vous pourriez imaginer pourquoi je voudrais voir les valeurs à une échelle log10. Essayons:

m + geom_boxplot() + coord_trans(y = "log10")

alt text

Comme vous pouvez le voir, l'axe y est mis à l'échelle log10 et semble bien, mais il y a un problème avec l'axe x, ce qui rend le tracé très étrange.

Le problème ne se produit pas avec scale_log, mais ce n'est pas une option pour moi, car je ne peux pas utiliser un formateur personnalisé de cette façon. Par exemple.:

m + geom_boxplot() + scale_y_log10() 

alt text

Ma question: quelqu'un connaît-il une solution pour tracer le boxplot avec une échelle log10 sur l'axe y dont les étiquettes pourraient être librement formatées avec une fonction formatter comme dans ce thread ?


Modification de la question pour aider les répondeurs en fonction des réponses et des commentaires:

Ce que je recherche vraiment: un axe (y) transformé log10 avec des étiquettes non scientifiques. Je voudrais l'étiqueter comme dollar (formatter=dollar) ou tout format personnalisé.

Si j'essaye la suggestion de @ hadley, j'obtiens les avertissements suivants:

> m + geom_boxplot() + scale_y_log10(formatter=dollar)
Warning messages:
1: In max(x) : no non-missing arguments to max; returning -Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

Avec un libellé d'axe y inchangé:

alt text

36
daroczig

Le plus simple est de donner simplement à l'argument "trans" (anciennement "formateur" le nom de la fonction log:

m + geom_boxplot() + scale_y_continuous(trans='log10')

EDIT: Ou si vous n'aimez pas cela, alors l'un ou l'autre semble donner des résultats différents mais utiles:

m <- ggplot(diamonds, aes(y = price, x = color), log="y")
m + geom_boxplot() 
m <- ggplot(diamonds, aes(y = price, x = color), log10="y")
m + geom_boxplot()

EDIT2 & 3: Autres expériences (après avoir écarté celle qui a réussi à mettre les signes "$" devant les valeurs enregistrées):

fmtExpLg10 <- function(x) paste(round_any(10^x/1000, 0.01) , "K $", sep="")
ggplot(diamonds, aes(color, log10(price))) + 
  geom_boxplot() + 
  scale_y_continuous("Price, log10-scaling", trans = fmtExpLg10)

alt text

Note ajoutée mi-2017 dans le commentaire sur le changement de syntaxe du package:

scale_y_continuous (formatter = 'log10') est maintenant scale_y_continuous (trans = 'log10') (ggplot2 v2.2.1)

26
42-

J'ai eu un problème similaire et cette échelle a fonctionné pour moi comme un charme:

breaks = 10**(1:10)
scale_y_log10(breaks = breaks, labels = comma(breaks))

comme vous voulez aussi les niveaux intermédiaires (10 ^ 3.5), vous devez ajuster la mise en forme:

breaks = 10**(1:10 * 0.5)
m <- ggplot(diamonds, aes(y = price, x = color)) + geom_boxplot()
m + scale_y_log10(breaks = breaks, labels = comma(breaks, digits = 1))

Après avoir exécuté ::

enter image description here

14
Susanne Oberhauser

Une autre solution utilisant scale_y_log10 Avec trans_breaks, trans_format Et annotation_logticks()

library(ggplot2)

m <- ggplot(diamonds, aes(y = price, x = color))

m + geom_boxplot() +
  scale_y_log10(
    breaks = scales::trans_breaks("log10", function(x) 10^x),
    labels = scales::trans_format("log10", scales::math_format(10^.x))
  ) +
  theme_bw() +
  annotation_logticks(sides = 'lr') +
  theme(panel.grid.minor = element_blank())

4
Tung

Je pense que je l'ai enfin obtenu en faisant des transformations manuelles avec les données avant la visualisation:

d <- diamonds
# computing logarithm of prices
d$price <- log10(d$price)

Et élaborez un formateur pour calculer ultérieurement les données logarithmiques:

formatBack <- function(x) 10^x 
# or with special formatter (here: "dollar")
formatBack <- function(x) paste(round(10^x, 2), "$", sep=' ') 

Et dessinez l'intrigue avec un formateur donné:

m <- ggplot(d, aes(y = price, x = color))
m + geom_boxplot() + scale_y_continuous(formatter='formatBack')

alt text

Désolé à la communauté de vous déranger avec une question que j'aurais pu résoudre avant! La partie amusante est: je travaillais dur pour faire fonctionner cette intrigue il y a un mois mais je n'y suis pas parvenue. Après avoir demandé ici, je l'ai compris.

Quoi qu'il en soit, merci à @DWin pour la motivation!

0
daroczig