web-dev-qa-db-ja.com

基本グラフィックスのプロット領域の外側に凡例をプロットしますか?

タイトルが言うように、基本グラフィックスを使用するとき、どのように私はプロット領域の外で凡例をプロットすることができますか?

layoutをいじって凡例だけを含む空のプロットを作成することを考えましたが、凡例のためにプロットの右側にスペースを確保するためにベースグラフ機能だけを使用する方法やpar(mar = )を使う方法に興味があります。


ここに例があります:

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
legend(1,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

生成されます:

alt text

しかし、言ったように、私は凡例をプロット領域の外側(例えば、グラフ/プロットの右側)にしたいと思います。

160
Henrik

たぶんあなたが必要とするものは物事がプロット領域の外に描かれることを可能にするためのpar(xpd=TRUE)です。ですから、もしあなたがbty='L'でメインプロットをするなら、あなたは凡例のためにいくらかのスペースを右側に持つでしょう。通常、これはプロット領域に切り取られますが、par(xpd=TRUE)を行い、少し調整すれば、可能な限り凡例を取得できます。

 set.seed(1) # just to get the same random numbers
 par(xpd=FALSE) # this is usually the default

 plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2), bty='L')
 # this legend gets clipped:
 legend(2.8,0,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

 # so turn off clipping:
 par(xpd=TRUE)
 legend(2.8,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))
101
Spacedman

insetに負のlegend値を使用することについて誰も言及していません。これは、凡例がプロットの右側にあり、上に配置されている例です(キーワード"topright"を使用)。

# Random data to plot:
A <- data.frame(x=rnorm(100, 20, 2), y=rnorm(100, 20, 2))
B <- data.frame(x=rnorm(100, 21, 1), y=rnorm(100, 21, 1))

# Add extra space to right of plot area; change clipping to figure
par(mar=c(5.1, 4.1, 4.1, 8.1), xpd=TRUE)

# Plot both groups
plot(y ~ x, A, ylim=range(c(A$y, B$y)), xlim=range(c(A$x, B$x)), pch=1,
               main="Scatter plot of two groups")
points(y ~ x, B, pch=3)

# Add legend to top right, outside plot region
legend("topright", inset=c(-0.2,0), legend=c("A","B"), pch=c(1,3), title="Group")

inset=c(-0.2,0)の最初の値は、凡例の幅に基づいて調整する必要があるかもしれません。

legend_right

131
Mike T

layoutまたはpar(xpd=TRUE)を使用して)既に述べたもの以外の別の解決策は、デバイス全体にあなたのプロットを透明なプロットでオーバーレイし、それに凡例を追加することです。

トリックは、プロット領域全体に(空の)グラフを重ねて、それに凡例を追加することです。 par(fig=...)オプションを使うことができます。まず、Rにプロット装置全体に新しいプロットを作成するように指示します。

par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), mar=c(0, 0, 0, 0), new=TRUE)

プロットの内部がデバイス全体をカバーするようにしたいので、omamarの設定が必要です。 new=TRUEはRが新しいデバイスを起動しないようにするために必要です。空のプロットを追加することができます。

plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')

凡例を追加する準備が整いました。

legend("bottomright", ...)

デバイスの右下に凡例が追加されます。同様に、凡例を上または右の余白に追加できます。唯一必要なことは、元のプロットの余白が凡例を収容するのに十分な大きさであるということです。

これらすべてを関数に入れます。

add_legend <- function(...) {
  opar <- par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), 
    mar=c(0, 0, 0, 0), new=TRUE)
  on.exit(par(opar))
  plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
  legend(...)
}

そして例です。最初に凡例を追加するのに十分なスペースが下部にあることを確認してプロットを作成します。

par(mar = c(5, 4, 1.4, 0.2))
plot(rnorm(50), rnorm(50), col=c("steelblue", "indianred"), pch=20)

それから伝説を加えなさい

add_legend("topright", legend=c("Foo", "Bar"), pch=20, 
   col=c("steelblue", "indianred"),
   horiz=TRUE, bty='n', cex=0.8)

その結果:

Example figure shown legend in top margin

24

私はこのようにするのが好きです:

par(oma=c(0, 0, 0, 5))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1,2))

enter image description here

必要な唯一の調整は、右マージンを凡例に対応するのに十分な幅に設定することです。

ただし、これは自動化することもできます。

dev.off() # to reset the graphics pars to defaults
par(mar=c(par('mar')[1:3], 0)) # optional, removes extraneous right inner margin space
plot.new()
l <- legend(0, 0, bty='n', c("group A", "group B"), 
            plot=FALSE, pch=c(1, 2), lty=c(1, 2))
# calculate right margin width in ndc
w <- grconvertX(l$rect$w, to='ndc') - grconvertX(0, to='ndc')
par(omd=c(0, 1-w, 0, 1))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2, 2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1, 2))

enter image description here

15
jbaums

古いスレッドを復活させて申し訳ありませんが、私は今日同じ問題を抱えていました。私が見つけた最も簡単な方法は次のとおりです。

# Expand right side of clipping rect to make room for the legend
par(xpd=T, mar=par()$mar+c(0,0,0,6))

# Plot graph normally
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

# Plot legend where you want
legend(3.2,1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

# Restore default clipping rect
par(mar=c(5, 4, 4, 2) + 0.1)

ここで見つかりました: http://www.harding.edu/fmccown/R/

14
veiga

最近私はあなたが望むプロット領域の外に凡例を印刷するための非常に簡単で面白い機能を見つけました。

プロットの右側に外側の余白を作ります。

par(xpd=T, mar=par()$mar+c(0,0,0,5))

プロットを作成する

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

以下のように凡例を追加してlocator(1)関数を使うだけです。それからあなたはただ次のスクリプトをロードした後にあなたが欲しいところをクリックする必要があります。

legend(locator(1),c("group A", "group B"), pch = c(1,2), lty = c(1,2))

それを試してみてください

9
Vandka

既に指摘したレイアウトソリューションの例を提供することしかできません。

layout(matrix(c(1,2), nrow = 1), widths = c(0.7, 0.3))
par(mar = c(5, 4, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
par(mar = c(5, 0, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, ylim=c(-2,2), type = "n", axes = FALSE, ann = FALSE)
legend(1, 1, c("group A", "group B"), pch = c(1,2), lty = c(1,2))

an ugly picture :S

8
Roman Luštrik

私の考えでは非常に優雅な別の単純な選択肢を追加する。

あなたのプロット:

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

伝説:

legend("bottomright", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(0,1), xpd=TRUE, horiz=TRUE, bty="n"
       )

結果:

picture with legend

ここでは凡例の2行目だけがあなたの例に追加されました。順番に:

  • inset=c(0,1) - 凡例をプロット領域の割合で(x、y)方向に移動します。この場合、凡例は"bottomright"の位置にあります。 x方向に0プロット領域だけ移動し(したがって "right"のまま)、y方向に1プロット領域だけ移動します(下から上へ)。そしてそれはプロットの真上に現れることが起こるのです。
  • xpd=TRUE - 凡例をプロット領域の外側に表示しましょう。
  • horiz=TRUE - 水平方向の凡例を作成するように指示します。
  • bty="n" - 凡例のバウンディングボックスを取り除くためのスタイルの詳細。

側面に凡例を追加する場合も同様です。

par(mar=c(5,4,2,6))
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

legend("topleft", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(1,0), xpd=TRUE, bty="n"
       )

ここでは、凡例の位置を調整し、プロットの右側に余白を追加しました。結果:

picture with legend 2

これは、 Plotly R API を使用するか、コードを使用するか、またはGUIから目的の場所に凡例をドラッグして実行できます。

これが一例です。グラフとコードも ここ です。

x = c(0,1,2,3,4,5,6,7,8) 
y = c(0,3,6,4,5,2,3,5,4) 
x2 = c(0,1,2,3,4,5,6,7,8) 
y2 = c(0,4,7,8,3,6,3,3,4)

Xまたはyの値のいずれかを100または-100に割り当てることで、凡例をグラフの外側に配置できます。

legendstyle = list("x"=100, "y"=1)
layoutstyle = list(legend=legendstyle)

他のオプションはここにあります:

  • 右下外側のlist("x" = 100, "y" = 0)
  • 右上の外側のlist("x" = 100, "y"= 1)
  • list("x" = 100, "y" = .5)右外中央
  • 左下のlist("x" = 0, "y" = -100)
  • 中央下list("x" = 0.5, "y" = -100)
  • 右下のlist("x" = 1, "y" = -100)

それから応答。

response = p$plotly(x,y,x2,y2, kwargs=list(layout=layoutstyle));

あなたが電話をかけるときにPlotlyはあなたのグラフでURLを返します。 browseURL(response$url)を呼び出すことでより早くアクセスすることができますので、ブラウザであなたのグラフを開くことができます。

url = response$url
filename = response$filename

それは私達にこのグラフを与えます。また、GUI内から凡例を移動すると、それに応じてグラフが拡大縮小されます。完全開示:私はPlotlyチームに所属しています。

Legend on side of graph

4
Mateo Sanchez

私が過去にこれに使用したlayout()を試してみてください。下に空のプロットを作成し、適切に1/4程度に縮尺し、その中に凡例部分を手動で配置してください。

legend()に関して、ここからいくつかの古い質問があります。

2