如何使用grImport导入的图形作为ggplot2中的轴刻度标签(使用网格函数)?

时间:2012-01-18 04:15:03

标签: r ggplot2 axis-labels r-grid

我希望我可以将grImport的漂亮导入和绘图功能与ggplot2的强大图形功能结合起来,但我根本不理解grid系统找到一种实现我想要的优雅方式。我想要的是用ggplot2替换grImport图表中的x轴刻度标签。

由于两个软件包都使用grid函数,我希望有一种方法可以在grid.symbols()框架内使用ggplot2,这是理想的,或者至少在现有框架中使用facet_grid在设备中绘图。知道这些事情的人是否知道这样做的有效方法?或者,任何人都可以向我指出更多信息,以帮助我了解grobs,视口等?我已经阅读了Grid图形模型上的free Chapter of Paul Murrel's R graphics book,但是我对ggplot2的内部工作原理并不熟悉,无法建立链接。

我的问题与an existing question about using an image as a plot point非常相似,虽然我对轴标签而不是绘图点更感兴趣。但是,我很好奇两个任务的相似程度,以及是否可以为此目的调整该解决方案。我无法独自解决这个问题。

这是我的第一篇文章,所以我不允许发布图片,但这段代码可以达到我想要的效果。注意:这种方法使用了一种丑陋,丑陋的黑客,它不便携,而且不尽如人意。我想要生成的最终图将具有构面(library(ggplot2) ## library(grImport) # not needed for this example, but would be for grid.symbols() p <- ggplot(mtcars, aes(cyl, mpg)) + stat_summary(fun.data = "mean_cl_boot") print(p) ## Replace (in this case, overlay) x-axis tick labels with a graphic / grob iconSize <- 0.05 iconHt <- 0.2 padding <- 0.09 # horizontal padding around axis: I found this by trial & error tickSp <- (1-padding)/(4*2) downViewport("axis_h-5-3") ## I would use grid.symbols() with an imported Picture in place of grid.circle(), ## but the idea is the same: draw a shape at the ticks along the axis. for (i in 0:(max(mtcars$cyl) - min(mtcars$cyl)) ) { grid.circle(x = (padding/2 + tickSp*(i*2)), y = iconHt, r = iconSize*(min(mtcars$cyl)+i), gp = gpar(fill="black")) } upViewport() ),x轴代表因子,每个轴刻度不同的图片,而不是连续变量,这就是为什么我正在寻找一个更通用/更强大的解决方案,不需要大量试用和错误。

{{1}}

3 个答案:

答案 0 :(得分:21)

这是一个例子:

# convert ps to RGML
PostScriptTrace(file.path(system.file(package = "grImport"), "doc", "GNU.ps"), "GNU.xml")
PostScriptTrace(file.path(system.file(package = "grImport"), "doc", "tiger.ps"), "tiger.xml")
# read xml
pics <- list(a = readPicture("GNU.xml"), b = readPicture("tiger.xml"))

# custom function for x axis label.
my_axis <- function () {
  structure(
      function(label, x = 0.5, y = 0.5, ...) {
         absoluteGrob(
           do.call("gList", mapply(symbolsGrob, pics[label], x, y, SIMPLIFY = FALSE)),
           height = unit(1.5, "cm"))
    }
)}

qplot(factor(c("a", "b")), 1:2) + opts( axis.text.x = my_axis())

enter image description here

答案 1 :(得分:6)

对于单个面板,从x轴grob中提取信息是相当简单的,并将其替换为您自己的。我不确定如何将它干净地扩展到自动多面板轴。

library(grid)
library(ggplot2)

p <- qplot(1:12, rnorm(12))
grid.newpage()
g <- ggplotGrob(p)
grid.draw(g)
g0 <- getGrob(g, gPath("axis.text.x"), grep=TRUE)
grid.set(gPath("axis.text.x"),
         pointsGrob(x = g0$x, y=0*g0$x + unit(0.5,"npc"),
                    pch=19, gp=gpar(col=seq_along(g0$x)),
                    name = g0$name), grep = TRUE)

screenshot

答案 2 :(得分:4)

下面是使用自定义grob进行轴标签的黑客攻击。

library(grid)
library(ggplot2)

## convert the labels to some parameter to be used in the custom grob
## here simply an index that will be interpreted as color
mapping <- function(x, ...){
  seq_along(x)
}

library(grImport)

hourglass <- new("Picture",
paths= list(new("PictureFill",
x=c(0, 1, 0, 1),
y=c(0, 0, 1, 1))),
summary= new("PictureSummary",
numPaths=1,
xscale=c(0, 1),
yscale=c(0, 1)))

## bare bones edit of theme_text()
my_axis <- function () 
{
    structure(function(label, x = 0.5, y = 0.5, default.units = "npc", ...) {
      cols <- mapping(label)

      symbolsGrob(hourglass, x, 0*x + unit(0.5, "npc"),
                  use.gc=FALSE,size=unit(5,"mm"), gp=gpar(fill=cols))

    }, class = "theme", type = "custom", call = match.call())
}

qplot(1:12, rnorm(12)) +
  opts( axis.text.x = my_axis(), axis.ticks.margin = unit(0.5, "cm"))

screenshot