什么是英寸?设置箭头的长度 [英] What is an inch? Setting the length for arrows

查看:124
本文介绍了什么是英寸?设置箭头的长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些莫名其妙的是,arrows中的length参数是以英寸为单位指定的(来自?arrows):

length箭头的边缘长度(以英寸为单位).

R源甚至在注释中甚至明确指出该尺寸以英寸为单位,突出了该设计的独特之处.

这意味着箭头的相对大小取决于dev.size().尚不清楚如何将英寸转换为轴单位(首先是无限多地有用).这是一个简化的版本:

h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
       length = .5*mean(diff(xs)))

此显示方式将取决于设备.例如.这是此设备上的输出:

png('test.png', width = 5, height = 5)

这里是另一个:

png('test.png', width = 8, height = 8)

视觉上有点虚幻,但在两个图中箭头的宽度确实相同.我该如何控制它,以便两个图(传达相同的数据)显示相同?更具体地说,如何确定箭头的宽度准确 .5 绘图单位?

?

解决方案

我在兔子洞上花了太多时间,可是到了.我将首先记录一下我的旅程,以帮助那些碰到这种情况的人,在尝试通过自举自足的时候,以各种角落和缝隙进行搜索.

我开始寻找arrows的源代码,但无济于事,因为它迅速进入了内部代码.因此,我在 R源中搜索了"C_arrows",以查找正在发生的情况.幸运的是,它是不是

检查?par(第1百万次),确实pinusr正是我们需要的图形参数(pin对我来说是新的,usr在这里和那里出现):

pin当前绘图尺寸(宽度,高度),以英寸为单位.

usr c(x1, x2, y1, y2)形式的向量,给出了绘制区域的用户坐标的极限.

因此,我们可以通过以下函数将绘图单位转换为 inches :

xinch_inv = function(dev_unit) {
    dev_unit * par("pin")[1L]/diff(par("usr")[1:2])
}

h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
       # just convert plot units to inches
       length = xinch_inv(.5*mean(diff(xs))))

产生(5x5):

和(8x8):

还要注意一点,它显示length是箭头的每一侧的长度-使用length = xinch_inv(.5), code = 3, angle = 90会得到与条形一样宽的段(即1). /p>

在您感兴趣的偶然机会下,我将它们打包在我的 package 中,作为xdev2in等;仅限GitHub.

Somewhat inexplicably, the length parameter in arrows is specified in inches (from ?arrows):

length length of the edges of the arrow head (in inches).

R source even goes so far as to explicitly make note that this measurement is in inches in a comment, highlighting how peculiar this design is.

That means the relative size of the arrows depends on dev.size(). What's not clear is how to translate inches into axis units (which are infinitely more useful in the first place). Here's a simplified version:

h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
       length = .5*mean(diff(xs)))

How this displays will depend on the device. E.g. here is the output on this device:

png('test.png', width = 5, height = 5)

And here it is on another:

png('test.png', width = 8, height = 8)

It's a bit of an optical illusion to tell on sight, but the arrows are indeed the same width in the two plots. How can I control this so that both plots (which convey the same data) display identically? More specifically, how can I make sure that the arrows are exactly .5 plot units in width?

解决方案

I spent far too much time in the rabbit hole on this, but here goes. I'll document a bit of my journey first to aid others who happen upon this in the types of nooks and crannies to search when trying to pull yourself up by your bootstraps.

I started looking in the source of arrows, but to no avail, since it quickly dives into internal code. So I searched the R source for "C_arrows" to find what's happening; luckily, it's not too esoteric, as far as R internal code goes. Poking around it seems the workhorse is actually GArrow, but this was a dead end, as it seems the length parameter isn't really transformed there (IIUC this means the conversion to inches is done for the other coordinates and length is untouched). But I happened to notice some GConvert calls that looked closer to what I want and hoped to find some user-facing function that appeals to these directly.

This led me to go back to R and to simply run through the gamut of functions in the same package as arrows looking for anything that could be useful:

ls(envir = as.environment('package:grDevices'))
ls(envir = as.environment('package:graphics'))

Finally I found three functions in graphics: xinch, yinch, and xyinch (all found on ?xinch) are used for the opposite of my goal here -- namely, they take inches and convert them into device units (in the x, y, and x&y directions, respectively). Luckily enough, these functions are all very simple, e.g. the work horse of xinch is the conversion factor:

diff(par("usr")[1:2])/par("pin")[1L]

Examining ?par (for the 1,000,000th time), indeed pin and usr are exactly the graphical parameter we need (pin is new to me, usr comes up here and there):

pin The current plot dimensions, (width, height), in inches.

usr A vector of the form c(x1, x2, y1, y2) giving the extremes of the user coordinates of the plotting region.

Hence, we can convert from plot units to inches by inverting this function:

xinch_inv = function(dev_unit) {
    dev_unit * par("pin")[1L]/diff(par("usr")[1:2])
}

h = c(1, 2, 3)
xs = barplot(h, space = 0, ylim = c(0, 4))
arrows(xs, h - .5, xs, h + .5,
       # just convert plot units to inches
       length = xinch_inv(.5*mean(diff(xs))))

Resulting in (5x5):

And (8x8):

One further note, it appears length is the length of each side of the arrow head -- using length = xinch_inv(.5), code = 3, angle = 90 results in segments as wide as the bars (i.e., 1).

On the off chance you're interested, I've packaged these in my package as xdev2in, etc.; GitHub only for now.

这篇关于什么是英寸?设置箭头的长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆