13

假设我有如下数据:

    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")

是否有可能将此图例显示为两排三排,而不是一排六排?

4

3 回答 3

5

尝试这个。我为很长的标题写了这个,但它适用于任何长字符串。您仍然需要计算实例的线长。

# 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 使用拆分标题

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")
于 2011-06-22T07:00:58.097 回答
5

要包装长字符串,请使用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.
于 2013-03-06T13:13:58.757 回答
2

前面提到的 splittitle几乎可以工作,但是例如

> 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)
}
于 2012-05-08T14:21:56.417 回答