我想使用tikzDevice
在ggplot2
文档中添加带注释的Latex
图表。
tikzAnnotate
帮助有一个如何将其与基本图形一起使用的示例,但如何将其与基于网格的绘图包(如ggplot2
)一起使用?挑战似乎是tikz节点的定位。
playwith
包有一个函数convertToDevicePixels
(http://code.google.com/p/playwith/source/browse/trunk/R/gridwork.R),似乎与grconvertX / grconvertY类似,但我也无法使其工作。
非常感谢有关如何继续的任何指示。
tikz使用基本图形注释示例
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()
答案 0 :(得分:7)
目前,tikzAnnotate
仅适用于基本图形。首次编写tikzAnnotate
时,grid
图形的问题在于我们需要一种指定相对于设备画布的绝对左下角的x,y坐标的方法。 grid
根据视口进行思考,在很多情况下,图形的最终坐标系统在通过print
函数前往设备之前是未知的。
拥有这个功能会很棒,但我无法找到一种实现它的好方法,因此该功能被搁置了。如果有人知道有关良好实施的详细信息,请随时在邮件列表上开始讨论(现在Google网上论坛上有alternate portal),它将会显示在TODO列表中。
更好的是,实现功能并在GitHub上打开对项目的拉取请求。这保证使该功能的发布速度比在TODO列表中保存数月的速度快9000倍。
我有一些时间来处理这个问题,我已经提出了一个函数,用于将当前视口中的网格坐标转换为绝对设备坐标:
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()
这给出了以下输出:
还有一些工作要做,例如:
创建可添加到网格图形的“注释grob”。
确定如何将此类对象添加到ggplot
。
这些功能是tikzDevice
的{{3}}。
答案 1 :(得分:2)
根据@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()
当然,这是一个相当狡猾的解决方案,但可以延长:
textGrob
的字符串的实际宽度计算文本的位置),