线型间距和大小的精确尺寸

Exact dimensions of linetype spacing and size

这主要是关于 的 follow-up 问题。

鉴于在ggplot2和grid中有不同的线型和线宽之间的间距不同,它们之间的关系是什么?

有两点不太明白

  1. 线宽是如何定义的?如果我要画一条直线并用一个矩形代替它,那么矩形的宽度应该是多少才能得到与直线大小相等的值?特别是,我传递给 par()/gpar()lwd = 1lwd = 10 与绝对尺寸(像素、毫米、英寸、点)有何关系?

gpar() 文档引用了 par() 文档,其中说明如下:

The line width, a positive number, defaulting to 1. The interpretation is device-specific, and some devices do not implement line widths less than one.

这很公平,但我真的找不到常见设备的必要设备特定文档。

  1. 我想我可能会假设不同线型的间距与其大小成正比,但是 'dotdash'、'dashed'、'dotted' 等 [=] 的比例到底是多少? 53=] 到 spacing-length 定义?

在下图中,如何提前预测或计算 dash/spacing 长度?

library(ggplot2)

df <- data.frame(
  x = rep(c(0, 1), 4),
  y = rep(1:4, each = 2),
  size = rep(c(2, 10), each = 4),
  linetype = rep(c(2,2,3,3), 2)
)

# The `I()` function automatically assigns identity scales
ggplot(df, aes(x, y, size = I(size), linetype = I(linetype))) +
  geom_line(aes(group = y))

我认为这主要是文档问题,所以如果您能指出正确的页面,我将非常高兴。否则,我上面两个问题的答案或演示也很好。

编辑:ggplot 有一个名为 .pt 的变量,他们经常使用它来乘以线宽。这可能意味着在网格中线的大小是 something / .pt,但单位是什么?

Teunbrand 的另一个好问题。我在这里有一个部分答案,它似乎给出了有效的结果,但感觉有点不精确。

lwd 和长度单位之间进行转换的明显方法是以编程方式测量它们。例如,要检查 X11 设备的 lwd,您可以这样做:

library(grid)

x11()
grid.newpage()

# draw a thick black line that goes right across the page
grid.draw(linesGrob(x = unit(c(-0.1, 1.1), "npc"), 
                    y = unit(c(0.5, 0.5), "npc"),
                    gp = gpar(lwd = 10)))

# Capture as a bitmap
bmp_line    <- dev.capture()

# Work out the thickness of the line in pixels as proportion of page height
lwd_10_prop <- sum(bmp_line != "white")/length(bmp_line)

# Now draw a black rectGrob of known height with lwd of 0 and transparent for completeness
grid.newpage()
grid.draw(rectGrob(width  = unit(1.1, "npc"),
                   height = unit(10, "mm"),
                   gp     = gpar(lwd = 0, col = "#00000000", fill = "black")))

# Capture as a bitmap and measure the width as proportion of device pixels
bmp_rect    <- dev.capture()
mm_10_prop  <- sum(bmp_rect != "white")/length(bmp_rect)

# Get the ratio of lwd to mm
lwd_as_mm <- lwd_10_prop / mm_10_prop
dev.off()

lwd_as_mm
#> [1] 0.2702296

这告诉我们 1 的 lwd 在这个设备上是 0.2702296 毫米

我们可以通过在页面顶部附近的绿线上绘制一个我们计算出的宽度的红色矩形来测试这一点,然后在页面底部附近的相同红色矩形上绘制相同的绿线。当且仅当它们的宽度完全相同时,我们的页面上才会有一条完全绿线和一条完全红线:

grid.newpage()

grid.draw(linesGrob(x = unit(c(-0.1, 1.1), "npc"), 
                    y = unit(c(0.75, 0.75), "npc"),
                    gp = gpar(lwd = 5, col = "green")))

grid.draw(rectGrob(y = unit(0.75, "npc"),
                   width  = unit(1.1, "npc"),
                   height = unit(5 * lwd_as_mm, "mm"),
                   gp     = gpar(lwd = 0,  col = "#00000000", fill = "red")))

grid.draw(rectGrob(y = unit(0.25, "npc"),
                   width  = unit(1.1, "npc"),
                   height = unit(5 * lwd_as_mm, "mm"),
                   gp     = gpar(lwd = 0,  col = "#00000000", fill = "red")))

grid.draw(linesGrob(x = unit(c(-0.1, 1.1), "npc"), 
                    y = unit(c(0.25, 0.25), "npc"),
                    gp = gpar(lwd = 5, col = "green")))

当然,我们可以通过在测量线条的像素宽度时增加线条的粗细来提高精度。

尽管结果应该与设备无关,但值得注意的是,在上面的示例中,我从 X11 设备中获取了结果,但将它们绘制在 rstudio 设备中,因此这两种设备似乎都是等价的。