1

我试图找出一种方法来计算图例的高度,然后再设置图的边距。我打算将图例放在 x 轴标签和标题下方的图下方。

因为它是绘制一系列事物的函数的一部分,所以图例的大小可以扩大和缩小以适应 2 个项目,最多 15 个或更多,所以我需要弄清楚如何动态地做到这一点,而不是硬编码. 所以,最后我需要动态设置边距和其他一些零碎的东西。

关键的挑战是在绘制图之前弄清楚要输入的图例的高度par(mar),但是在剖析图例的基本代码之后,除非实际绘制了图,否则似乎不可能得到高度值的可靠估计(鸡肉和鸡蛋有人吗?)

这是我已经尝试过的:

  1. 使用基本图例函数的输出获取高度legend$rect$h(这似乎给出了一个不正确的高度值,除非实际绘制了绘图)

  2. 计算图例中的行数(简单)并将其乘以行高(为了做到这一点,似乎您需要转换为英寸(基本图例代码使用 yinch,我也尝试过grconvertY,但两者都没有)除非已经绘制了情节,否则这些工作)。

另一个挑战是计算出放置图例的正确 y 值 - 我认为一旦我解决了第一个挑战,第二个挑战就会很容易。

编辑:

经过一天的努力,这()是如何工作的。我有一些见解和几个问题。为了清楚起见,这就是我的函数本质上所做的:

步骤 1) 设置边距

步骤 2) 在左轴上创建条形图

步骤 3) 重新设置 usr 坐标 - 这是确保右轴对齐所必需的,否则它会根据 x 轴比例绘制。当它们明显不同时不好。

步骤 4) 创建右轴

步骤 5) 在右轴上创建一系列折线图

步骤 6) 对两个轴和 x 轴进行一些标记

步骤 7) 添加图例

以下是问题

Q1) 报告的单位是什么?我对边缘线和坐标(用户坐标)感兴趣,英寸是不言自明的。- 我可以使用 grconvertY() 进行一些转换,但我不确定我在看什么以及我应该转换成什么 - 文档不是很好。

Q2) 我需要在步骤 1 中设置边距,以便图表底部有足够的空间放置图例。我想我做对了,但是我需要在设置右轴和折线图之后设置图例,这意味着用户坐标(以及一英寸的像素值已经改变。因为上面的 Q1 我'我不确定如何将一个系统转换为另一个系统。这方面的任何想法都将不胜感激。

4

1 回答 1

0

经过又一天的汗流浃背,这主要是为我解决了这个问题。

我将核心图例函数的代码拆开并编译:

#calculate legend buffer
cin <- par("cin")
Cex <- par("cex")
yc <- Cex * cin[2L] #cin(inches) * maginfication
yextra <- 0
ymax <- yc * max(1, strheight("Example", units = "inches", cex = Cex)/yc)
ychar <- yextra + ymax #coordinates
legendHeight <- (legendLines * ychar) + yc # in

这本质上是在模仿核心函数计算图例高度的方式,但以英寸而不是用户坐标返回高度。legendLines 是图例中的行数。

之后,要弄清楚如何放置图例并正确设置下边距是一件轻而易举的事。我在用着:

#calculate inches per margin line
inchesPerMarLine<-par("mai")[1]/par("mar")[1]

计算每条边距线的英寸数,然后设置缓冲区(用于轴标签和标题,以及图表的底部)和绘图的边距。

#set buffers
bottomBuffer = 1
buffer=2

#calculate legend buffer
legBuffer <- legendHeight/inchesPerMarLine

#start the new plot
plot.new()

# set margin
bottomMargin <- buffer + legBuffer + bottomBuffer
par(mar=c(bottomMargin,8,3,5))

剧情制作完成

barplot(data, width=1, col=barCol, names.arg=names,  ylab="", las=1 ,axes=F, ylim=c(0,maxL), axis.lty=1)

然后放置图例。我使用了一种不同的方法来提取图例宽度,当有一个 1 点的图例时确实会遇到一些挑战,但是,它现在可以正常工作。将图例放入变量中允许您访问框的宽度,例如l$rect$w. trace=TRUEplot=FALSE停止将传说写入情节。

ycoord <- -1*(yinch(inchesPerMarLine*buffer)*1.8)
l<-legend(x=par("usr")[1], y=ycoord, inset=c(0,-0.25), legendText, fill=legendColour, horiz=FALSE, bty = "n", ncol=3, trace=TRUE,plot=FALSE)
lx <- mean(par("usr")[1:2]-(l$rect$w/2))
legend(x=lx, y=ycoord, legendText, fill=legendColour, horiz=FALSE, bty = "n", ncol=3)

为了完整起见,这就是我计算图例中行数的方式。注意 - 图例中的列数为 3。 labelSeries 是图例标签的列表。

legendLines <- ceiling(nrow(labelSeries)/3)
于 2014-05-16T01:04:46.773 回答