2011-06-21 12 views
13

Supongamos que tengo los datos como los siguientes:Wrap leyenda horizontal a través de varias filas

lab <- "A really really long string!" 
    dat <- data.frame(grp = paste(1:6,lab),x=1:6,y=runif(6)) 

Al trazar una leyenda con las cadenas esta larga, a veces puede ser un reto para conseguir la leyenda para encajar muy bien. Si tengo que hacerlo, siempre puedo abreviar las cadenas para acortarlos, pero me preguntaba si es posible (lo más probable es que use algo de magia grid) para 'envolver' una leyenda en múltiples filas o columnas. Por ejemplo, digamos que la posición de la leyenda en la parte inferior, horizontal:

ggplot(dat,aes(x=x,y=y,colour=grp)) + geom_point() + 
     opts(legend.position="bottom",legend.direction="horizontal") 

¿Es posible obtener esta leyenda para mostrar como dos filas de tres, en lugar de una fila de seis?

+2

No es lo que está pidiendo, pero puede encontrarse con que 'laboratorio <-. "! Una muy \ n larga \ nSTRING" 'o algo similar podría ayudar a encajar la leyenda en – Henry

+0

acabo pidió esto en el GitHub porque después de sugerir facet_wrap, me gustaría la leyenda en el espacio en blanco y tiene que ser de dos filas o dos columnas. –

Respuesta

5

Envolver cadenas largas, utilizar strwrap.

lipsum <- "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ullamcorper tellus vitae libero placerat aliquet egestas tortor semper. Maecenas pellentesque euismod tristique. Donec semper interdum magna, commodo vehicula ante hendrerit vitae. Maecenas at diam sollicitudin magna mollis lobortis. In nibh elit, tincidunt eu lobortis ac, molestie a felis. Proin turpis leo, iaculis non commodo quis, venenatis at justo. Duis in magna vel erat fringilla gravida quis non nisl. Nunc lacus magna, varius eu luctus vel, luctus tristique sapien. Suspendisse mi dolor, vestibulum at facilisis elementum, lacinia vitae metus. Etiam ut nisl urna, vel tempus mi. In hac habitasse platea dictumst. Quisque pretium volutpat felis, nec tempor diam faucibus at. Praesent volutpat posuere sapien, eu vulputate risus molestie vitae. Proin iaculis quam non leo porttitor hendrerit." 

strwrap(lipsum) 
cat(strwrap(lipsum), sep = "\n") 
# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ullamcorper tellus 
# vitae libero placerat aliquet egestas tortor semper. Maecenas pellentesque euismod 
# tristique. Donec semper interdum magna, commodo vehicula ante hendrerit vitae. Maecenas 
# at diam sollicitudin magna mollis lobortis. In nibh elit, tincidunt eu lobortis ac, 
# molestie a felis. Proin turpis leo, iaculis non commodo quis, venenatis at justo. Duis 
# in magna vel erat fringilla gravida quis non nisl. Nunc lacus magna, varius eu luctus 
# vel, luctus tristique sapien. Suspendisse mi dolor, vestibulum at facilisis elementum, 
# lacinia vitae metus. Etiam ut nisl urna, vel tempus mi. In hac habitasse platea 
# dictumst. Quisque pretium volutpat felis, nec tempor diam faucibus at. Praesent 
# volutpat posuere sapien, eu vulputate risus molestie vitae. Proin iaculis quam non leo 
# porttitor hendrerit. 
+1

suspiro. – joran

5

Pruebe esto. Escribí esto para títulos muy largos, pero funciona para cualquier cadena larga. Aún debe calcular la longitud de línea para su instancia.

# splits title of plot if to long 
splittitle=function(title,linelength=40) 
{ 
    spltitle<-strsplit(title,' ') 
    splt<-as.data.frame(spltitle) 
    title2<-NULL 
    title3<-NULL 
    titlelength<-round(nchar(title)/round(nchar(title)/linelength)) 
    dimsplt<-dim(splt) 
    n=1 
    doonce2=0 
    for(m in 1:round(nchar(title)/linelength)){ 
    doonce=0 
    doonce2=0 
    for(l in n:dimsplt[1]){ 
     if(doonce==0){title2<-title3} 
     title2=paste(title2,splt[l,],sep=' ') 
     if(doonce2==0){if(nchar(title2)>=(titlelength*m)){title3=paste(title2,'\n',sep='') 
     n<-(l+1) 
     doonce2=1} 
     } 
     doonce=1 
    } 
    } 
    title2 
} 

lab <- "A really really long string!A really really long string!A really really long string!A really really long string!A really really long string!A really really long string!A really really long string!A really really long string!" 
lab2<-splittitle(lab) 
cat(lab) 
cat(lab2) 


library('ggplot2') 

1 original de

dat <- data.frame(grp = paste(1:6,lab2),x=1:6,y=runif(6)) 

ggplot(dat,aes(x=x,y=y,colour=grp)) + geom_point() + 
    opts(legend.position="bottom",legend.direction="horizontal") 

2 usando splittitle

dat <- data.frame(grp = paste(1:6,lab2),x=1:6,y=runif(6)) 
ggplot(dat,aes(x=x,y=y,colour=grp)) + geom_point() + 
    opts(legend.position="bottom",legend.direction="horizontal") 
+0

+1 para el código útil para dividir cadenas largas. – joran

2

El splittitle anteriormente mencionada casi obras, pero por ejemplo

> splittitle("abc defg hi jkl m", 6)
[1] " abc defg\n hi\n jkl m"

en realidad no le dará lo que quiere ...

Un truco es usar RGraphics::splitString cuales

"divide una sola cadena en múltiples líneas (insertando saltos de línea) por lo que la salida encajará dentro de la ventana gráfica actual ".

Luego solo cambia la ventana temporalmente. La función a continuación hizo el truco para mí, pero sigue siendo solo una solución & sucia. Lo usé para envolver un título de leyenda.

library(RGraphics) 
multiLines <- function(text, maxWidth=11) { 
    textLen = nchar(text) 
    maxHeight = ceiling(textLen/maxWidth)*1.5 
    vp=viewport(width=maxWidth,height=maxHeight, default.units="char") 
    pushViewport(vp) #activate the viewport 
    text2 = splitString(text) #given vp, split the text 
    popViewport() #get rid of it 
    return(text2) 
} 
Cuestiones relacionadas