如何在 r 图中为多个图例自动定位图例?

Posted

技术标签:

【中文标题】如何在 r 图中为多个图例自动定位图例?【英文标题】:How to automate legend positioning in r plot for multiple legends? 【发布时间】:2019-11-05 06:03:17 【问题描述】:

我正在制作一个 R 图,并希望并排放置几个图例(在绘图区域之外)。目标是自动放置图例。

我正在使用这里的方法:https://***.com/a/34624632/4978977

这是示例代码,图右侧有两个图例:

dev.off()
par(mar=c(par('mar')[1:3], 0))
plot.new()
l1 <- legend(0, 0, bty='n', c("group A", "group B"), plot=FALSE, pch=c(1, 2), lty=c(1, 2))
l2 <- legend(0, 0, bty='n', c("group A", "group B"), plot=FALSE, pch=c(1, 2), lty=c(1, 2))
w1 <- grconvertX(l1$rect$w, to='ndc') - grconvertX(0, to='ndc')
w2 <- grconvertX(l2$rect$w, to='ndc') - grconvertX(0, to='ndc')
par(omd=c(0, 1-sum(w1, w2), 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))
legend(par('usr')[2]+l1$rect$w, par('usr')[4], bty='n', xpd=NA, c("group A", "group B"), pch=c(1, 2), lty=c(1, 2))

我可以直观地在绘图右侧获得适当的边距,以便为两个图例并排获得足够的空间。

据我了解l1$rect$w 是“用户”坐标中第一个图例的宽度。正如您在代码中看到的 - 我将此值添加到第一个图例的左侧位置以获得第二个图例位置。 结果是第二个图例向右移动但不够远,它与第一个图例的文本重叠。

如何正确指定第二个图例的位置,使其不与第一个图例重叠?

【问题讨论】:

我知道它不能回答您的问题,但我强烈建议您使用 ggplot2 包以获得相同的结果。 ggplot2 有很多方法可以以编程方式调整所有绘图元素的大小、位置等 【参考方案1】:

你可以做的更简单:

# expand margin on the right side for the legend
par(mar=c(par("mar")[1:3], 13.1))

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

# add the lines
lines(1:3, rnorm(3), pch=2, lty=2, type="o")

# add the first legend and save it's position
l1 <- legend("topleft", c("group A", "groupB"), bty='n', xpd=TRUE, 
             pch=c(1,2), lty=c(1,2), inset=c(1,0))

# add second legend and adjust x axis position based on width of first legend
legend(l1$rect$left+l1$rect$w, l1$rec$top, c("group A", "groupB", "groupC"),
       bty='n', xpd=TRUE, pch=c(1,2,3), lty=c(1,2,3), inset=c(1,0))

注意一些“技巧”:

    我使用了xpd=TRUE,因此即使在主绘图区域之外也能显示图例。 对于第一个图例,我将位置指定为“左上角”,然后使用 inset=c(1,0) - 这会将图例移动绘图区域的分数(1 = 整个绘图区域),从而方便地将其放置在绘图之外。

【讨论】:

谢谢。虽然这适用于问题中描述的具有相等长度的图例的特定情况,但这种设置 ncol 的方法在图例长度不相等的情况下失败 - 例如,尝试第一个图例 2 行,第二个图例 3 行。 谢谢 - 这就是方法!我还使用par(mar=c(par('mar')[1:3], grconvertX(l1$rect$w + l2$rect$w, to='lines'))) 自动设置边距 关于边距 - 你不是必须先画一个图,知道l1$rect$w 是什么才能设置边距吗?我假设你会制作两次情节? 您可以使用plot = FALSE 制作没有情节的图例(类似于我在原始问题中的代码):l1 &lt;- legend(0, 0, bty='n', c("group A", "group B"), plot=FALSE, pch=c(1, 2), lty=c(1, 2))。然后你可以得到l1$rect$w - 不需要绘图

以上是关于如何在 r 图中为多个图例自动定位图例?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Plotly 的图中定位图例

如何在 seaborn 散点图中编辑多个图例框?

我如何在 R 的图中修复图例

在 R plotly 子图中,如何只显示一个图例?

在基础R的散点图中转换图例的形状和颜色

如何在python的散点图中添加具有不同标记的多个图例?