Trasformare un solo asse di scala log10 con ggplot2
-
11-10-2019 - |
Domanda
ho il seguente problema: Vorrei visualizzare una discreta ed una variabile continua su un grafico a scatole in cui quest'ultimo presenta alcuni valori estremi elevati. Questo rende l'insignificante boxplot (i punti e anche il "corpo" del grafico è troppo piccolo), ecco perché desidero mostrarlo su scala log10. Sono consapevole che avrei potuto lasciare i valori estremi dalla visualizzazione, ma non mi intendevo.
Vediamo un semplice esempio con i dati di diamanti:
m <- ggplot(diamonds, aes(y = price, x = color))
Il problema non è grave qui, ma spero che si possa immaginare perché mi piacerebbe vedere i valori in scala log10. Proviamo:
m + geom_boxplot() + coord_trans(y = "log10")
Come si può vedere l'asse y è log10 scalato e sembra bene, ma c'è un problema con l'asse x, il che rende la trama molto strano.
Il problema non si verifica con scale_log
, ma questo non è un'opzione per me , come non riesco a usare un costume formattatore in questo modo. Per esempio:.
m + geom_boxplot() + scale_y_log10()
La mia domanda: qualcuno sa di una soluzione per tracciare il grafico a scatole con la scala log10 sull'asse y che le etichette possano essere liberamente formattati con una funzione formatter
come in questo filo ?
Modifica della domanda di aiuto answerers sulla base di risposte e commenti:
Quali sono davvero dopo: uno log10 asse trasformato (y) con etichette non scientifiche. Vorrei etichettarlo come dollaro (formatter=dollar)
o qualsiasi formato personalizzato.
Se provo @ di Hadley suggerimento ottengo le seguenti avvertenze:
> 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
Con un y invariata all'asse etichette:
Soluzione
Il più semplice è quello di dare il proprio (ex 'formattatore' argomento 'trans' il nome della funzione di log:
m + geom_boxplot() + scale_y_continuous(trans='log10')
EDIT: O se non lo fai così, allora uno di questi sembra dare risultati diversi ma utili:
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: Ulteriori esperimenti (dopo aver scartato quella che ha tentato con successo di mettere "$" segni di fronte a valori registrati):
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)
Nota aggiunta a metà 2017 in un commento sul cambiamento della sintassi del pacchetto:
scale_y_continuous (formattatore = 'log10') è ora scale_y_continuous (= trans 'log10') (ggplot2 v2.2.1)
Altri suggerimenti
Ho avuto un problema simile e questa scala funzionato per me come un fascino:
breaks = 10**(1:10)
scale_y_log10(breaks = breaks, labels = comma(breaks))
come si desidera che i livelli intermedi, anche (10 ^ 3.5), è necessario modificare la formattazione:
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))
Dopo l'esecuzione ::
Un'altra soluzione utilizzando scale_y_log10
con trans_breaks
, trans_format
e 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())
Credo di aver capito finalmente facendo alcune trasformazioni manuali con i dati prima di visualizzazione:
d <- diamonds
# computing logarithm of prices
d$price <- log10(d$price)
E il lavoro fuori un formattatore per poi calcolare 'indietro' i dati logaritmiche:
formatBack <- function(x) 10^x
# or with special formatter (here: "dollar")
formatBack <- function(x) paste(round(10^x, 2), "$", sep=' ')
E disegnare la trama con data formattatore:
m <- ggplot(d, aes(y = price, x = color))
m + geom_boxplot() + scale_y_continuous(formatter='formatBack')
Ci dispiace per la comunità di disturbarla con una domanda che avrebbe potuto risolvere prima! La parte divertente è: Stavo lavorando duramente per fare questo lavoro trama di un mese fa, ma non ci sono riuscito. Dopo aver chiesto qui, ho capito.
In ogni caso, grazie a @DWin per la motivazione!