Обернуть горизонтальную легенду через несколько строк - PullRequest
13 голосов
/ 22 июня 2011

Предположим, у меня есть данные, подобные следующим:

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

При построении легенды со строками так долго, иногда может быть непросто подобрать легенду, чтобы она подходила по размеру.Если мне нужно, я всегда могу сокращать строки, чтобы укоротить их, но мне было интересно, возможно ли (скорее всего, с использованием магии grid) «обернуть» легенду в несколько строк или столбцов.Например, скажем, я расположил легенду внизу по горизонтали:

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

Можно ли отобразить эту легенду в виде двух рядов из трех, а не из одного ряда из шести?

Ответы [ 3 ]

5 голосов
/ 06 марта 2013

Чтобы обернуть длинные строки, используйте 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.
5 голосов
/ 22 июня 2011

Попробуй это. Я написал это для очень длинных заголовков, но это работает для любой длинной строки. Вы все еще должны выяснить длину строки для вашего экземпляра.

# 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 оригинал

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 с использованием 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")
2 голосов
/ 08 мая 2012

Ранее упомянутое разделение почти работает, но, например,

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

на самом деле не дает вамхочу ...

Одна хитрость заключается в использовании RGraphics::splitString, который

"Разбивает одну строку на несколько строк (вставляя разрывы строк), чтобы выходные данные помещались в пределахтекущий видовой экран. "

Тогда вы просто временно меняете видовой экран.Приведенная ниже функция помогла мне, но это все еще быстрое и грязное решение.Я использовал это, чтобы обернуть название легенды.

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)
}
...