调整水平图例中文本之间的间距

May*_*you 12 plot r legend

我有一个带有水平图例的情节:

 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)
Run Code Online (Sandbox Code Playgroud)

问题是图例的第一项"AAPL"和第二项"信息技术"之间存在巨大的间距.

我尝试使用调整间距txt.width(),但它根本不起作用.或者我可能没有按照指示使用此选项.这就是我在txt.width内部引入选项的方法legend():

txt.width = c(2,1,1)
Run Code Online (Sandbox Code Playgroud)

我不确定它是否相关,但我的x轴是日期轴!

有没有一种简单的方法来自定义图例中文本之间的空格?

谢谢!

And*_*lva 14

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)
Run Code Online (Sandbox Code Playgroud)

horizo​​ntal_legend

我使用text.width了四个参数来设置图例中字符串之间的空格.text.width中的第二个参数设法设置"AAPL"和"信息技术"之间的距离,依此类推第三个和第四个参数.

不幸的是,我text.width每次更改绘图大小时都需要重置值.


pan*_*gia 13

text.width可以让您控制图例中每列的宽度,但这并不简单.基本上,text.width是一个向量,它将乘以另一个向量,该向量与图例字符串的向量一样长.该第二向量的元素是从整数0length(legend)-1.有关详细信息,请参阅代码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)
Run Code Online (Sandbox Code Playgroud)

然后你的最终代码看起来像这样(除了我们不知道你原来的绘图数据或参数):

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)
Run Code Online (Sandbox Code Playgroud)

正如安德烈·席尔瓦提到的,价值观,你会想xcoordstextwidths将取决于你的阴谋的电流的大小,值的范围指定为你的x轴等.

此外,secondvector如果每列有多个元素,则上面看起来会有所不同.例如,对于具有两个图例元素的两列,secondvector == c(0,0,1,1).


RFe*_*ber 5

在我的系统(平台:x86_64-w64-mingw32,R 版本:3.4.1 (2017-06-30))上,Andre Silva 和 pangja 迄今为止提供的解决方案并不令人满意。这两种解决方案都需要用户输入并取决于设备尺寸。因为我从来不习惯这个text.width命令,而且总是不得不通过试错来调整值,所以我写了函数 ( f.horlegend)。该函数具有与函数相似的参数,legend并且基于此处发布的想法。

该函数创建一个水平(一行)图例,可以通过函数中已知的命令进行定位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)

}
Run Code Online (Sandbox Code Playgroud)

参数

pos 图例的位置(c(“bottomleft”,“bottom”,“bottomright”,“left”,“center”,“right”,“topleft”,“top”,“topright”))

legend 图例文字

xoff 在 x 方向调整位置。注意:图例绘制在一个图上,limits = c(0,1)

yoff 与 xoff 相同,但在 y 方向

lty 线型。线型只能指定为整数(0=空白,1=实线(默认),2=虚线,3=虚线,4=点划线,5=长划线,6=双划线)

lwd 线宽,正数,默认为1

ln.col 线条颜色

seg.len 线的长度,默认为 0.04

pch 指定符号的整数。

pt.col 符号颜色。

pt.bg 符号的背景颜色。

pt.cex 符号的扩展因子

pt.lwd 符号的线宽

text.cex 文本的扩展因子

text.col 文字颜色

text.font 文字字体

text.vfont 请参阅文本帮助中的 vfont

bty 要在图例周围绘制的框的类型。允许的值为“o”(默认值)和“n”

bbord 图例框边框的颜色

bbg 背景颜色

blty 边框样式

blwd 边框线宽

bdens 线的密度,请参阅段帮助

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)
Run Code Online (Sandbox Code Playgroud)