2014-12-14 11 views
5

Ho una trama le cui etichette sono fattori della forma "1990-2012". Sono troppo lunghi e/o ce ne sono troppi e si sovrappongono.Dividi le etichette su 2 righe in ggplot con i fattori

enter image description here

Vorrei stampare ogni etichetta su due linee e rompere dopo il trattino, qualcosa di simile:

enter image description here

Per le situazioni in cui si infrangono le etichette in due parti sarebbe ancora non è sufficiente, mi piacerebbe anche sapere come stampare solo ogni altra etichetta.

Un vincolo che ho è che l'etichettatura deve essere eseguita "sul posto" senza pre-elaborazione di data.frame e/o etichette, anche se una funzione personalizzata applicata all'interno della chiamata a ggplot andrebbe bene.

Ecco la dataframe sacrosanta (non può essere modificato):

df <- structure(list(Period = structure(1:13, .Label = c("0-1000", 
    "1000-1500", "1500-1700", "1700-1820", "1820-1913", "1913-1950", 
    "1950-1970", "1970-1990", "1990-2012", "2012-2030", "2030-2050", 
    "2050-2070", "2070-2100"), class = "factor"), value = c(0.000168759866884916, 
    0.000989913144738397, 0.00159894629454382, 0.0045594248070473, 
    0.00585564273031225, 0.00932876890888812, 0.0191066122563939, 
    0.0183146076484786, 0.0130117469870081, 0.00923670910453378, 
    0.00560791817163286, 0.00272731553972227, 0.00149387241891397 
    ), variable = c("World", "World", "World", "World", "World", 
    "World", "World", "World", "World", "World", "World", "World", 
    "World")), .Names = c("Period", "value", "variable"), row.names = c(NA, 
    -13L), class = "data.frame") 

Ecco la ggplot:

library(ggplot2) 
    p <- ggplot(data = df, aes(x = Period, y = value, group = variable)) + geom_line() + theme_bw() 

Il seguente avrebbe funzionato, se ho avuto uno spazio dopo il trattino:

library(stringr) 
    p + scale_x_discrete(labels = function(x) str_wrap(x, width = 4)) 

[Le due righe precedenti sono state utilizzate per produrre il secondo grafico, dopo aver modificato manualmente il datafra me per aggiungere uno spazio vuoto dopo il trattino data di separazione, in altre parole, dopo ho barato]

il seguente approccio per stampare un numero inferiore di etichette di solito funziona, ma non riesce qui:

library(scales) 
    p + scale_x_discrete(breaks = pretty_breaks(n = 6)) 

risposta

6

E 'questo che stai cercando?

p + scale_x_discrete(
    labels=function(x){ 
    x2 <- sub("(\\d+)\\-(\\d+)", 
       "\\1\\-\n\\2", 
       x) 
    x2 
    }) 

enter image description here

realtà l'intermedio x2 non è neppure necessario, questo

p + scale_x_discrete(
    labels=function(x){ 
    sub("(\\d+)\\-(\\d+)","\\1\\-\n\\2",x) 
    }) 

è un po 'più compatta.

Edit: Una soluzione ancora più conciso, grazie a @jlhoward:

p + scale_x_discrete(
    labels=function(x) sub("-","-\n",x,fixed=TRUE)) 
+1

Grazie @nrussell, nel frattempo mi sono reso conto che avrei potuto usare '' str_replace'' dal '' stringr' 'pacchetto. Mi ero perso, avevo perso tempo in '' str_sub'' di non rendermi conto che c'era un '' str_replace'' per il lavoro. La soluzione '' stringr'' è: '' p + scale_x_discrete (labels = function (x) str_wrap (str_replace (x, "-", "-"), width = 4)) '' – PatrickT

+0

Una soluzione lungo le linee suggerisco è quello che mi aspettavo, ma non so come funzionano questi backslash e '' d + '' e mi convinco di non riuscire mai a risolverlo. E guardando il termine all'interno di '' sub() '', è chiaro che non sono riuscito a inventarlo da solo! Grazie, :-) – PatrickT

+1

Prego; '\\ d +' è una scorciatoia per "1 o più cifre consecutive" nella sintassi delle espressioni regolari.I backslash che precedono il trattino potrebbero o non essere stati necessari - alcuni simboli regex hanno un significato speciale e devono essere sfuggiti (doppio escape in R e in alcune altre lingue) per essere interpretati letteralmente; Ho sempre dimenticato esattamente quali sono, quindi lo faccio con la maggior parte dei simboli solo per essere sicuro. '\\ 1' fa riferimento al primo gruppo di cattura (il' (\\ d +) ') e' \\ 2' fa riferimento al secondo '(\\ d +)'. Vedi [qui] (http://www.rexegg.com/regex-quickstart.html). – nrussell

Problemi correlati