Использование grconvertX/grconvertY в ggplot2

Я пытаюсь выяснить, как использовать grconvertX/grconvertX в ggplot. Моя конечная цель - добавить аннотацию к рисунку ggplot2 (и, возможно, к решетке) с помощью grid.text а также grid.lines перейдя от пользовательских координат к координатам устройства. Я знаю, что это можно сделать с помощью грабов, но мне интересно, есть ли более простой способ.

Следующий код позволяет мне передавать значения из пользовательских координат в координаты ndc и использовать эти значения для аннотирования графика с помощью grid.text,

graphics.off()      # close graphics windows   

library(grid)
library(gridBase)


test= data.frame(
  x = c(1,2,3),
  y = c(12,10,3),
  n = c(75,76,73)
  )

par(mar = c(13,5,2,3))

plot(test$y ~ test$x,type="b", ann=F)

for (i in 1:nrow(test))

{
  X=grconvertX(i , from="user", to="ndc")
  grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5))   ) ) 
  grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}
#add some code to save as PDF ...

Код основан на решении одного из моих предыдущих постов: Смешивание систем координат X и Y. Вы можете увидеть, как координаты х из исходного графика были преобразованы в ndc. Преимущество этого подхода в том, что я могу использовать координаты устройства для Y.

Я предположил, что могу легко сделать то же самое в ggplot2 (и, возможно, в решетке).

library(ggplot2)
graphics.off()      # close graphics windows   

qplot(x=x, y=y, data=test)+geom_line()+  opts(plot.margin = unit(c(1,3,8,1), "lines"))

for (i in 1:nrow(test))

{
  X=grconvertX(i , from="user", to="ndc")
  grid.text(x=X, y =0.2, label=paste("GRID.text at\nuser.x=", i, "\n", "ndc.x=", (signif( X, 5))   ) ) 
  grid.lines(x=c(X, X), y = c(0.28, 0.33) )
}

#add some code to save as PDF...

Тем не менее, это не работает правильно. Координаты, кажется, немного смещены. Вертикальные линии и текст не соответствуют галочкам на графике. Кто-нибудь может сказать мне, как это исправить? Заранее большое спасибо.

1 ответ

Решение

grconvertX а также grconvertY функции работают с базовой графикой, а ggplot2 использует сеточную графику. В общем, два разных графических движка не очень хорошо играют вместе (хотя вы продемонстрировали, что gridBase помогать). Ваш первый пример работает, потому что вы начали с базового графика, поэтому существует пользовательская система координат с базовым графиком и grconvertX новообращенных из него. Во втором случае пользовательская система координат никогда не была установлена ​​в базовой графике, поэтому похоже, что она может использовать координаты по умолчанию 0,1, которые похожи, но не идентичны координатам верхнего окна просмотра, так что вы получите что-то похожее, но не совсем правильное (Я действительно удивлен, что вы не получили ошибку или предупреждение

Как правило, для сеточной графики эквивалент для преобразования координат состоит в том, чтобы просто создать новый видовой экран с интересующей системой координат (или нажать / выдвинуть в существующий видовой экран с правильной системой координат), а затем добавить свои аннотации в этот видовой экран.

Вот пример, который создает ваш график, затем перемещается вниз к окну просмотра, содержащему основной график, создает новый видовой экран с теми же размерами, но с отключенным отсечением, масштаб x основан на данных, а масштаб y равен 0,1, а затем добавляет текст соответственно:

library(ggplot2)
library(grid)

test= data.frame(   x = c(1,2,3),   y = c(12,10,3),   n = c(75,76,73)   )  

qplot(x=x, y=y, data=test)+geom_line()+  opts(plot.margin = unit(c(1,3,8,1), "lines"))  

current.vpTree()
downViewport('panel-3-4')
pushViewport(dataViewport( test$x, clip='off',yscale=c(0,1)))

for (i in 1:nrow(test))  {
    grid.text(x=i, y = -0.2, default.units='native',
        label=paste("GRID.text at\nuser.x=", i, "\n"   ) )
        grid.lines(x=c(i, i), y = c(-0.1, 0), default.units='native' )
 } 

Одна из хитростей в этом заключается в том, что ggplot2 не устанавливает масштабы области просмотра в соответствии с отображаемыми данными, а выполняет сами преобразования. В этом случае настройка масштаба на основе данных x сработала, но если ggplot2 делает что-то более причудливое, это может не сработать. Нам понадобится какой-то способ получить обратно преобразованные координаты из ggplot2 для использования в вызове grid.text.

Другие вопросы по тегам