2013-12-13 19 views
30

Edit: Questa domanda è stata contrassegnata come duplicato, ma le risposte here sono stati provati e non funzionava perché il caso in questione è un grafico lineare, non una barra grafico. L'applicazione di questi metodi produce un grafico con 5 linee, 1 per ogni anno: non utile. Qualcuno che ha votato per contrassegnare come duplicato prova effettivamente quegli approcci sul set di dati campione fornito con questa domanda? In tal caso, si prega di postare come risposta.più corone etichette di asse x in grafico lineare ggplot

domanda iniziale:

C'è una caratteristica nei grafici pivot di Excel che consente a più livelli axes.I'm categorica cercando di trovare un modo per fare la stessa cosa con ggplot (o qualsiasi altro pacchetto di plotting in R) .

Si consideri il seguente set di dati:

set.seed(1) 
df=data.frame(year=rep(2009:2013,each=4), 
       quarter=rep(c("Q1","Q2","Q3","Q4"),5), 
       sales=40:59+rnorm(20,sd=5)) 

Se questo viene importato in una tabella pivot di Excel, è semplice per creare la seguente tabella:

Si noti come l'asse x ha due livelli, uno per trimestre e uno per la variabile di raggruppamento, anno. Gli assi multilivello sono possibili con ggplot?

NB: C'è un trucco con faccette che produce qualcosa di simile, ma questo non è quello che sto cercando.

library(ggplot2) 
ggplot(df) + 
    geom_line(aes(x=quarter,y=sales,group=year))+ 
    facet_grid(.~year,scales="free") 

risposta

39

Usiamo argomenti in theme per rimuovere il testo predefinito x asse (axis.title.x/axis.text.x = element_blank()) e sono aggiunti i margini aggiuntivi (plot.margin).

Le nuove etichette vengono aggiunte utilizzando annotate(geom = "text",. Convertendo l'oggetto grafico in un grob (ggplot_gtable(ggplot_build(), è possibile disattivare il ritaglio delle etichette dell'asse x.

library(ggplot2) 
g1 <- ggplot(data = df, aes(x = interaction(year, quarter, lex.order = TRUE), 
          y = sales, group = 1)) + 
    geom_line(colour = "blue") + 
    coord_cartesian(ylim = c(35, 65), expand = FALSE) + 
    annotate(geom = "text", x = seq_len(nrow(df)), y = 34, label = df$quarter, size = 4) + 
    annotate(geom = "text", x = 2.5 + 4 * (0:4), y = 32, label = unique(df$year), size = 6) + 
    theme_bw() + 
    theme(plot.margin = unit(c(1, 1, 4, 1), "lines"), 
     axis.title.x = element_blank(), 
     axis.text.x = element_blank(), 
     panel.grid.major.x = element_blank(), 
     panel.grid.minor.x = element_blank()) 


# remove clipping of x axis labels 
g2 <- ggplot_gtable(ggplot_build(g1)) 
g2$layout$clip[g2$layout$name == "panel"] <- "off" 
grid::grid.draw(g2) 

enter image description here


Vedi anche la bella risposta da @ eipi10 qui: Prevent showing the year several times unnecessarily with time series

+0

Molto bello! Inoltre, l'uso di 'x = interazione (anno, trimestre)' è nuovo per me. – jlhoward

20

Il codice suggerito da Henrik funziona e mi ha aiutato molto! Penso che la soluzione abbia un alto valore. Ma per favore sii consapevole che esiste una piccola misstake nella prima riga del codice, che risulta in un ordine errato dei dati. Invece di

... aes(x = interaction(year,quarter), ... 

dovrebbe essere

... aes(x = interaction(quarter,year), ... 

Il grafico risultante ha i dati nel giusto ordine.

enter image description here

P.S. Ho suggerito una modifica (che è stata respinta fino ad ora) e, a causa di una piccola mancanza di reputazione, non ho il permesso di commentare, quello che avrei preferito fare.

Problemi correlati