2014-01-21 80 views
11

我有一個水平的傳說一個情節:調整文字之間的間距在水平傳說

legend("bottomleft", inset = c(0, -0.3), bty = "n", 
     x.intersp=0, xjust=0,yjust=0, 
     legend=c("AAPL", "Information Technology", 
       "Technology Hardware and Equipment", "S&P 500"), 
     col=c("black", "red", "blue3", "olivedrab3"), 
     lwd=2, cex = 0.5, xpd = TRUE, ncol = 4) 

的問題是,有傳說,「AAPL」的第一項,第二之間的巨大空間項目「信息技術」。

我嘗試過使用txt.width()調整間距,但它根本不起作用。或者也許我沒有按照指示使用這個選項。這是我已經介紹裏面legend()txt.width選項:

txt.width = c(2,1,1) 

我不知道,如果它要提及,但我的X軸是日期的軸線!

是否有一種簡單的方法來自定義圖例中的文本之間的空格?

謝謝!

回答

9

text.width可以讓您控制圖例中每列的寬度,但這不是直接的。基本上,text.width是一個矢量,它將與另一個矢量相乘,這個矢量與圖例字符串的矢量一樣長。第二個矢量的元素是從0length(legend)-1的整數。血腥細節見code to legend()。重要的是,您可以將text.width的這個乘積和第二個向量看作您的圖例元素的x座標。然後如果你知道你想要的x座標,你可以計算text.width參數中需要傳遞的內容。

legtext <- c("AAPL", "Information Technology", 
      "Technology Hardware and Equipment", "S&P 500") 
xcoords <- c(0, 10, 30, 60) 
secondvector <- (1:length(legtext))-1 
textwidths <- xcoords/secondvector # this works for all but the first element 
textwidths[1] <- 0 # so replace element 1 with a finite number (any will do) 

然後你的最終代碼可能看起來是這樣的(但我們不知道你的原始繪圖數據或參數):

plot(x=as.Date(c("1/1/13","3/1/13","5/1/13"), "%m/%d/%y"), y=1:3, ylim=c(0,3)) 

legend(x="bottomleft", bty = "n", x.intersp=0, xjust=0, yjust=0, 
    legend=legtext, 
    col=c("black", "red", "blue3", "olivedrab3"), 
    lwd=2, cex = 0.5, xpd = TRUE, ncol = 4, 
    text.width=textwidths) 

安德烈·席爾瓦提到的,值你會想要在xcoordstextwidths將取決於您的地塊的當前大小,爲您的X軸指定的值的範圍等。

而且,secondvector上面看起來不同,如果你有多個元素每列。例如,對於兩個具有兩個圖例元素的列,secondvector == c(0,0,1,1)

11
plot(1,1,xlab="",ylab="",xlim=c(0,2),ylim=c(0,2)) 

legend("bottomleft", text.width=c(0,0.085,0.235,0.35), 
     inset = c(0, -0.2), bty = "n", x.intersp=0.5, 
     xjust=0, yjust=0, 
     legend=c("AAPL", "Information Technology", 
       "Technology Hardware and Equipment", "S&P 500"), 
     col=c("black", "red", "blue3", "olivedrab3"), 
     lwd=3, cex = 0.75, xpd = TRUE, horiz=TRUE) 

horizontal_legend

我用text.width用四個參數設置在圖例中的字符串之間的空間。 text.width中的第二個參數設置了「AAPL」和「信息技術」之間的距離,第三和第四個參數等等。

不幸的是,我需要在每次更改打印尺寸時重置text.width中的值。

0

在我的系統(平臺:x86_64-w64-mingw32,R版本:3.4.1(2017-06-30))上,Andre Silva和pangja提供的解決方案並不令人滿意。這兩種解決方案都需要用戶輸入並取決於設備的大小。由於我從來沒有習慣text.width命令,並始終不得不通過嘗試錯誤來調整值,所以我編寫了函數(f.horlegend)。該函數具有與函數legend相似的參數,並基於張貼的想法here

該函數創建一個水平(一行)圖例,該圖例可以通過函數legend已知的命令(例如, "bottomleft"

f.horlegend <- function(pos, legend, xoff = 0, yoff = 0, 
    lty = 0, lwd = 1, ln.col = 1, seg.len = 0.04, 
    pch = NA, pt.col = 1, pt.bg = NA, pt.cex = par("cex"), pt.lwd = lwd, 
    text.cex = par("cex"), text.col = par("col"), text.font = NULL, text.vfont = NULL, 
    bty = "o", bbord = "black", bbg = par("bg"), blty = par("lty"), blwd = par("lwd"), bdens = NULL, bbx.adj = 0, bby.adj = 0.75 
) { 

    ### get original par values and re-set them at end of function 
    op <- par(no.readonly = TRUE) 
    on.exit(par(op)) 

    ### new par with dimension [0,1] 
    par(new=TRUE, xaxs="i", yaxs="i", xpd=TRUE) 
    plot.new() 

    ### spacing between legend elements 
    d0 <- 0.01 * (1 + bbx.adj) 
    d1 <- 0.01 
    d2 <- 0.02 
    pch.len <- 0.008 
    ln.len <- seg.len/2 

    n.lgd <- length(legend) 

    txt.h <- strheight(legend[1], cex = text.cex, font = text.font, vfont = text.vfont) *(1 + bby.adj) 
    i.pch <- seq(1, 2*n.lgd, 2) 
    i.txt <- seq(2, 2*n.lgd, 2) 

    ### determine x positions of legend elements 
    X <- c(d0 + pch.len, pch.len + d1, rep(strwidth(legend[-n.lgd])+d2+pch.len, each=2)) 
    X[i.txt[-1]] <- pch.len+d1 

    ### adjust symbol space if line is drawn 
    if (any(lty != 0)) { 
    lty <- rep(lty, n.lgd)[1:n.lgd] 
    ln.sep <- rep(ln.len - pch.len, n.lgd)[lty] 
    ln.sep[is.na(ln.sep)] <- 0 
    X <- X + rep(ln.sep, each=2) 
    lty[is.na(lty)] <- 0 
    } 

    X <- cumsum(X) 

    ### legend box coordinates 
    bstart <- 0 
    bend <- X[2*n.lgd]+strwidth(legend[n.lgd])+d0 

    ### legend position 
    if (pos == "top" | pos == "bottom" | pos == "center") x_corr <- 0.5 - bend/2 +xoff 
    if (pos == "bottomright" | pos == "right" | pos == "topright") x_corr <- 1. - bend + xoff 
    if (pos == "bottomleft" | pos == "left" | pos == "topleft") x_corr <- 0 + xoff 

    if (pos == "bottomleft" | pos == "bottom" | pos == "bottomright") Y <- txt.h/2 + yoff 
    if (pos == "left" | pos == "center" | pos =="right") Y <- 0.5 + yoff 
    if (pos == "topleft" | pos == "top" | pos == "topright") Y <- 1 - txt.h/2 + yoff 

    Y <- rep(Y, n.lgd) 
    ### draw legend box 
    if (bty != "n") rect(bstart+x_corr, Y-txt.h/2, x_corr+bend, Y+txt.h/2, border=bbord, col=bbg, lty=blty, lwd=blwd, density=bdens) 

    ### draw legend symbols and text 
    segments(X[i.pch]+x_corr-ln.len, Y, X[i.pch]+x_corr+ln.len, Y, col = ln.col, lty = lty, lwd = lwd) 
    points(X[i.pch]+x_corr, Y, pch = pch, col = pt.col, bg = pt.bg, cex = pt.cex, lwd = pt.lwd) 
    text(X[i.txt]+x_corr, Y, legend, pos=4, offset=0, cex = text.cex, col = text.col, font = text.font, vfont = text.vfont) 

} 

參數

pos圖例(C( 「BOTTOMLEFT」, 「底」, 「bottomright」, 「左」, 「中心」, 「右」 的位置, 「左上」 , 「頂部」, 「topright」))

legend圖例文本

xoff adjustement的在x方向上的位置。 NB:圖例被繪製在曲線圖與限制= C(0,1)

`yoff``作爲XOFF相同,但沿y directin

lty的線類型。線類型只能指定爲整數(0 =空白,1 =實線(默認),2 =虛線,3 =虛線,4 =點號,5 = longdash,6 = twodash)

lwd線寬,一個正數,默認爲1

ln.col線條顏色

seg.len該線的長度,deafult至0.04

pch一個整數,指定符號。

pt.col符號顏色。

pt.bg符號的背景顏色。用於符號

`符號的pt.lwd``線寬

text.cex膨脹係數爲文本

text.col文本顏色

text.font文字字體

pt.cex擴展因子

text.vfont請參閱文本幫助中的vfont

bty要在圖例周圍繪製的框的類型。允許的值是 「○」(缺省值)和 「n」

bbord顏色圖例框邊界的

bbg背景顏色

blty邊界風格

blwd邊界線寬度

bdens線密度,請參見segment-help

bbx.adj相對值增加文本和水平禁區線之間的空間

bby.adj一樣bbx.adj但是對於垂直BOC線

不幸的是,我沒有時間在此刻創建一個包。但隨意使用該功能。歡迎任何意見和想法來改善功能。

一些例子

plot(1:100, rnorm(100)) 
lgd.text <- c("12", "12") 
sapply(c("bottomleft", "bottom", "bottomright", "left", "center", "right", "topleft", "top", "topright"), function(x) f.horlegend(x, lgd.text, pch=16, lty=c(NA, 1), bbg="orange")) 


plot(1:100, rnorm(100)) 
lgd.text <- c("12", "132", "12345") 
f.horlegend("topleft", lgd.text, pch=NA) 
f.horlegend("top", lgd.text, pch=NA, bby.adj=1.5, bbord="red") 
f.horlegend("left", lgd.text, xoff=0.2, pch=1, bby.adj=0, bbord="red", bbg="lightgreen") 
f.horlegend("left", lgd.text, xoff=0.2, yoff=-0.05, pch=c(NA, 1, 6), lty=1, bbx.adj=2, bby.adj=0, bbord="red", bbg="lightgreen") 

f.horlegend("topright", lgd.text, yoff=0.1, pch=c(1,2,NA), lty=c(NA, NA, 2), bbord="red", blty=2, blwd=2) 

lgd.text <- c("12", "123456", "12345", "123") 
f.horlegend("bottom", lgd.text, yoff=0.1, pch=c(1,2,NA), lty=c(NA, 1, 2), text.font=2) 
f.horlegend("bottom", lgd.text, pch=c(1,2,NA), lty=c(NA, 1, 2), text.font=c(1,2,3)) 

plot(seq(as.POSIXct("2017-08-30"), as.POSIXct("2017-09-30"), by="weeks"), rnorm(5), type="l") 
f.horlegend("topleft", "random values", lty=1)