水平凡例付きのプロットがあります:
_ 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」と2番目の項目「情報技術」の間に大きな間隔があることです。
txt.width()
を使用して間隔を調整しようとしましたが、まったく機能しませんでした。または、指示どおりにこのオプションを使用していません。これは、legend()
内に_txt.width
_オプションを導入した方法です。
_txt.width = c(2,1,1)
_
それが言及に関連するかどうかはわかりませんが、私のx軸は日付の軸です!
凡例のテキスト間のスペースをカスタマイズする簡単な方法はありますか?
ありがとう!
_text.width
_を使用すると、凡例の各列の幅を制御できますが、簡単ではありません。基本的に、_text.width
_は、凡例文字列のベクトルと同じ長さの別のベクトルで乗算されるベクトルです。その2番目のベクトルの要素は、_0
_からlength(legend)-1
までの整数です。詳細は code to legend()
を参照してください。重要なことは、この_text.width
_と2番目のベクトルの積を凡例の凡例要素の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)
_
Andre Silvaが述べたように、xcoords
とtextwidths
に必要な値は、プロットの現在のサイズ、x軸に指定された値の範囲などによって異なります。
また、列ごとに複数の要素がある場合、上記のsecondvector
は異なるように見えます。たとえば、2つの凡例要素が2つある2つの列の場合、secondvector == c(0,0,1,1)
です。
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)
text.width
を4つの引数とともに使用して、凡例の文字列間のスペースを設定しました。 text.width内の2番目の引数は、「AAPL」と「情報技術」の間の距離を設定することに成功し、3番目と4番目の引数についても同様です。
残念ながら、プロットサイズを変更するたびにtext.width
内の値をリセットする必要がありました。
私のシステム(プラットフォーム:x86_64-w64-mingw32、Rバージョン:3.4.1(2017-06-30))では、Andre Silvaとpangjaがこれまでに提供したソリューションは満足のいくものではありません。どちらのソリューションもユーザー入力を必要とし、デバイスのサイズに依存します。私はtext.width
コマンドに慣れず、常に試行錯誤で値を調整する必要があったため、関数(f.horlegend
)を作成しました。この関数は、関数legend
と同様の引数を持ち、投稿されたアイデア here に基づいています。
関数は、水平(1行)の凡例を作成します。凡例は、関数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"、 "bottom"、 "bottomright"、 "left"、 "center"、 "right"、 "topleft"、 "top"、 "topright"))
legend
凡例テキスト
xoff
x方向の位置の調整。注意:凡例は、limits = c(0,1)のプロットにプロットされます
yoff
xoffと同じですが、y-directinにあります
lty
線種。線種は整数としてのみ指定できます(0 =空白、1 =実線(デフォルト)、2 =破線、3 =点線、4 =点線、5 =長い線、6 = 2線)
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)
私の場合、水平方向に5つの凡例がありました。各凡例の間隔をカスタマイズする必要があります。以下は、この目的のためのコードスニペットです。
legend("topright",horiz = T, legend = df2, fill = col_box,
inset = c(-0.2,-0.1), xpd = TRUE, bty = 'n', density = density_value, angle = angle_value, x.intersp=0.3,
text.width=c(3.5,3.4,3.7,4.3,7))
text.width
魔法をかける関数