Ответ 1
Я провел слишком много времени в кроличьей дыре, но здесь. Сначала я запишу немного о своем путешествии, чтобы помочь другим, которые случаются на этом в типах укромных уголков и трещин, чтобы искать, пытаясь подтянуть себя своими бутстрапами.
Я начал искать источник arrows
, но безрезультатно, так как он быстро погружается во внутренний код. Поэтому я искал источник R для "C_arrows"
, чтобы узнать, что происходит; к счастью, не слишком эзотерический, поскольку внутренний код R идет. Кажется, что рабочая лошадка на самом деле GArrow
, но это был тупик, так как кажется, что параметр length
не является действительно преобразованный там (IIUC это означает, что преобразование в дюймы выполняется для других координат, а length
нетронутым). Но я заметил несколько вызовов GConvert
, которые были ближе к тому, что я хочу, и надеялись найти какую-то пользовательскую функцию, которая обращается к ним напрямую.
Это заставило меня вернуться к R и просто запустить гамму функций в том же пакете, что и arrows
, ища все, что может быть полезно:
ls(envir = as.environment('package:grDevices'))
ls(envir = as.environment('package:graphics'))
Наконец, я нашел три функции в graphics
: xinch
, yinch
и xyinch
(все найденные на ?xinch
) используются для противоположности моей цели здесь - а именно, они занимают дюймы и конвертировать их в единицы устройства (соответственно в направлениях x, y и x & y). К счастью, эти функции очень просты, например. рабочая лошадь xinch
является коэффициентом пересчета:
diff(par("usr")[1L:2])/par("pin")[1L]
Изучая ?par
(в течение 1,000,000-го раза), действительно pin
и usr
являются именно графическим параметром, который нам нужен (pin
является новым для меня, usr
появляется здесь и там):
pin
Текущие размеры участка (ширина, высота) в дюймах.
usr
Вектор формыc(x1, x2, y1, y2)
, дающий экстремумы пользовательских координат области построения.
Следовательно, мы можем преобразовать из единиц измерения в дюймы путем инвертирования этой функции:
xinch_inv = function(dev_unit) {
dev_unit * par("pin")[1L]/diff(par("usr")[1L:2L])
}
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).
В случае непредвиденных обстоятельств вас интересует, я упаковал их в пакет как xdev2in
и т.д.; GitHub только сейчас.