Аннотируйте графики ggplot2, используя tikzAnnotate в tikzDevice - PullRequest
7 голосов
/ 16 февраля 2011

Я хотел бы использовать tikzDevice для включения аннотированных ggplot2 графиков в Latex документ.

tikzAnnotate Справка содержит пример того, как использовать ее с базовой графикой, но как использовать ее с пакетом построения на основе сетки, таким как ggplot2? Похоже, проблема заключается в позиционировании узла тикз.

Пакет

playwith имеет функцию convertToDevicePixels (http://code.google.com/p/playwith/source/browse/trunk/R/gridwork.R), которая похожа на grconvertX / grconvertY, но я не могу заставить это работать либо.

Буду признателен за любые указания о том, как действовать.

tikzAnnotate пример с использованием базовой графики

library(tikzDevice)
library(ggplot2)
options(tikzLatexPackages = c(getOption('tikzLatexPackages'),
                "\\usetikzlibrary{shapes.arrows}"))
tikz(standAlone=TRUE)

print(plot(15:20, 5:10))
#print(qplot(15:20, 5:10))

x <- grconvertX(17,,'device')
y <- grconvertY(7,,'device')
#px <- playwith::convertToDevicePixels(17, 7)
#x <- px$x
#y <- px$y

tikzAnnotate(paste('\\node[single arrow,anchor=tip,draw,fill=green] at (',
                x,',',y,') {Look over here!};'))
dev.off()

resulting image

Ответы [ 2 ]

7 голосов
/ 19 февраля 2011

В настоящее время tikzAnnotate работает только с базовой графикой. Когда tikzAnnotate был впервые написан, проблема с графикой grid заключалась в том, что нам требовался способ указания координат x, y относительно абсолютного нижнего левого угла холста устройства. grid мыслит в терминах областей просмотра, и во многих случаях кажется, что окончательная система координат графики неизвестна, пока она не направляется к устройству с помощью функции print.

Было бы замечательно иметь эту функцию, но я не мог найти хороший способ реализовать ее, и поэтому эта функция была отложена. Если у кого-то есть сведения о хорошей реализации, не стесняйтесь начинать обсуждение в списке рассылки (который теперь имеет альтернативный портал в группах Google), и он попадет в список TODO.

Еще лучше реализовать функциональность и открыть запрос на извлечение проекта на GitHub . Это гарантирует, что эта функция будет выпущена в 9000 раз быстрее, чем если бы она месяцами находилась в моем списке TODO.


Обновление

У меня было время поработать над этим, и у меня появилась функция для преобразования координат сетки в текущем окне просмотра в абсолютные координаты устройства:

gridToDevice <- function(x = 0, y = 0, units = 'native') {
  # Converts a coordinate pair from the current viewport to an "absolute
  # location" measured in device units from the lower left corner. This is done
  # by first casting to inches in the current viewport and then using the
  # current.transform() matrix to obtain inches in the device canvas.
  x <- convertX(unit(x, units), unitTo = 'inches', valueOnly = TRUE)
  y <- convertY(unit(y, units), unitTo = 'inches', valueOnly = TRUE)

  transCoords <- c(x,y,1) %*% current.transform()
  transCoords <- (transCoords / transCoords[3])

  return(
    # Finally, cast from inches to native device units
    c(
      grconvertX(transCoords[1], from = 'inches', to ='device'),
      grconvertY(transCoords[2], from = 'inches', to ='device')
    )
  )

}

Используя этот недостающий фрагмент, можно использовать tikzAnnotate для разметки grid или lattice сюжета:

require(tikzDevice)
require(grid)
options(tikzLatexPackages = c(getOption('tikzLatexPackages'),
                "\\usetikzlibrary{shapes.arrows}"))

tikz(standAlone=TRUE)

xs <- 15:20
ys <- 5:10

pushViewport(plotViewport())
pushViewport(dataViewport(xs,ys))

grobs <- gList(grid.rect(),grid.xaxis(),grid.yaxis(),grid.points(xs, ys))

coords <- gridToDevice(17, 7)
tikzAnnotate(paste('\\node[single arrow,anchor=tip,draw,fill=green,left=1em]',
  'at (', coords[1],',',coords[2],') {Look over here!};'))

dev.off()

Это дает следующий вывод:

TikZ Annotation of Grid Graphics


Еще предстоит проделать определенную работу, например:

  • Создание "аннотации", которая может быть добавлена ​​к сетке графики.

  • Определите, как добавить такой объект в ggplot.

Эти функции должны появиться в версии 0.7 из tikzDevice.

2 голосов
/ 19 февраля 2011

Я составил небольшой пример, основанный на предложении @ Andrie с geom_text и geom_polygon:

Инициализация ваших данных:

df <- structure(list(x = 15:20, y = 5:10), .Names = c("x", "y"), row.names = c(NA, -6L), class = "data.frame")

И вам нужно аннотировать4-ая строка в наборе данных, текст должен быть: «Посмотрите сюда!»

point <- df[4,]
ptext <- "Look over here!"

Создайте красивую стрелку, рассчитанную из координат указанной выше точки:

arrow <- data.frame(
    x = c(point$x-0.1, point$x-0.3, point$x-0.3, point$x-2, point$x-2, point$x-0.3, point$x-0.3, point$x-0.1),
    y = c(point$y, point$y+0.3, point$y+0.2, point$y+0.2, point$y-0.2, point$y-0.2, point$y-0.3, point$y)
)

А также сделайте некоторые вычисления для положения текста:

ptext <- data.frame(label=ptext, x=point$x-1, y=point$y)

Больше ничего не нужно делать, кроме черчения:

ggplot(df, aes(x,y)) + geom_point() + geom_polygon(aes(x,y), data=arrow, fill="green") + geom_text(aes(x, y, label=label), ptext) + theme_bw()

example image of annotating ggplot2 with arrow signs

Конечно,это довольно хакерское решение, но его можно расширить:

  • вычисляет размер стрелки на основе диапазонов x и y ,
  • вычислить положение текста на основе длины текста (или реальной ширины строки с помощью textGrob),
  • определить форму, которая не перекрывает ваши точки:)

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...