问题描述
在上一个问题中,我问了如何获得用户坐标中的边界线位置.我以 line2user
函数的形式收到了一个很好的答案.但是,当 x 或 y 轴在对数刻度上时,我无法弄清楚如何修改该函数以使其工作.
In a previous question I asked how to get margin line locations in user coordinates. I received an excellent answer in the form of the line2user
function. However, I cannot figure out how to modify the function to work when either the x or y axis is on a log scale.
我进行了一些修改以适应对数缩放轴:
I have made a couple modifications to accommodate a log-scaled axis:
line2user <- function(line, side, log = "") {
lh <- par('cin')[2] * par('cex') * par('lheight')
x_off <- diff(grconvertX(0:1, 'inches', 'user'))
y_off <- diff(grconvertY(0:1, 'inches', 'user'))
usr <- par('usr') ## Added by me
if (grepl("x", log)) usr[1:2] <- 10^usr[1:2] ## Added by me
if (grepl("y", log)) usr[3:4] <- 10^usr[3:4] ## Added by me
switch(side,
`1` = usr[3] - line * y_off * lh,
`2` = usr[1] - line * x_off * lh,
`3` = usr[4] + line * y_off * lh,
`4` = usr[2] + line * x_off * lh,
stop("Side must be 1, 2, 3, or 4", call.=FALSE))
}
但是,我无法弄清楚如何正确调整 xoff
和 yoff
变量以绘制正确的线条.插图:
However, I cannot figure out how to properly adjust the xoff
and yoff
variables to draw the proper lines. Illustration:
setup_plot <- function(log = "") {
par(mar = c(2, 10, 2, 2), oma = rep(2, 4))
plot.new()
plot.window(xlim = c(1, 10), ylim = c(1, 10), log = log)
box(which = "plot", lwd = 2, col = "gray40")
box(which = "figure", lwd = 2, col = "darkred")
box(which = "outer", lwd = 2, col = "darkgreen")
text(x = 0.5, y = 0.5,
labels = "Plot Region",
col = "gray40", font = 2)
mtext(side = 3, text = "Figure region", line = 0.5, col = "darkred", font = 2)
mtext(side = 3, text = "Device region", line = 2.5, col = "darkgreen", font = 2)
for (i in 0:9) {
mtext(side = 2, col = "darkred", text = paste0("Line", i), line = i)
}
}
setup_plot(log = "x")
abline(v=line2user(line=0:9, side=2, log = "x"), xpd=TRUE, lty=2)
考虑以下示例后,压缩行是有意义的:
The compressed lines make sense after considering the following example:
plot(10)
diff(grconvertX(0:1, 'inches', 'user'))
## [1] 0.08121573 (on my device)
plot(10, log = "x")
diff(grconvertX(0:1, 'inches', 'user'))
## [1] 0.0297354 (on my device)
在使用对数缩放轴时如何获得正确的 x_off
和 y_off
值?
How can I get the correct x_off
and y_off
values when working with a log-scaled axis?
推荐答案
这是一个适用于对数刻度和线性刻度轴的版本.诀窍是在 npc
坐标而不是 user
坐标中表示行位置,因为当轴在对数刻度上时,后者当然不是线性的.
Here's a version that works with log-scale and linear scale axes. The trick is to express line locations in npc
coordinates rather than user
coordinates, since the latter are of course not linear when axes are on log scales.
line2user <- function(line, side) {
lh <- par('cin')[2] * par('cex') * par('lheight')
x_off <- diff(grconvertX(c(0, lh), 'inches', 'npc'))
y_off <- diff(grconvertY(c(0, lh), 'inches', 'npc'))
switch(side,
`1` = grconvertY(-line * y_off, 'npc', 'user'),
`2` = grconvertX(-line * x_off, 'npc', 'user'),
`3` = grconvertY(1 + line * y_off, 'npc', 'user'),
`4` = grconvertX(1 + line * x_off, 'npc', 'user'),
stop("Side must be 1, 2, 3, or 4", call.=FALSE))
}
这里有几个例子,用 mar=c(5, 5, 5, 5)
应用到你的 setup_plot
:
And here are a couple of examples, applied to your setup_plot
with mar=c(5, 5, 5, 5)
:
setup_plot()
axis(1, line=5)
axis(2, line=5)
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE)
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE)
setup_plot(log='x')
axis(1, line=5)
axis(2, line=5)
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE)
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE)
setup_plot(log='y')
axis(1, line=5)
axis(2, line=5)
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE)
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE)
setup_plot(log='xy')
axis(1, line=5)
axis(2, line=5)
abline(h=line2user(0:4, 1), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 2), lty=3, xpd=TRUE)
abline(h=line2user(0:4, 3), lty=3, xpd=TRUE)
abline(v=line2user(0:4, 4), lty=3, xpd=TRUE)
这篇关于获取日志空间中的边际线位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!