Как я могу использовать графику, импортированную с grImport, в качестве меток тиков оси в ggplot2 (используя функции сетки)?
Я надеюсь, что смогу объединить возможности импорта и рисования grImport
с удивительной графикой ggplot2
но я просто не понимаю grid
Система достаточно хорошо, чтобы найти элегантный способ достижения того, что я хочу. То, что я хочу, это заменить метки оси X в ggplot2
график с изображениями, импортированными с использованием grImport
,
Поскольку оба пакета используют grid
функции, я надеюсь, что есть способ использовать grid.symbols()
либо в пределах ggplot2
рамки, которая была бы идеальной, или, по крайней мере, на существующий сюжет в устройстве. Кто-нибудь с большим знанием таких вещей знает надежный способ сделать это? Или кто-нибудь может указать мне дополнительную информацию, чтобы помочь мне узнать о гробах, окнах просмотра и т. Д.? Я прочитал бесплатную главу книги о графике Пола Меррела R о графической модели Grid, но я недостаточно знаком с внутренней работой ggplot2, чтобы создать ссылку.
Мой вопрос очень похож на существующий вопрос об использовании изображения в качестве точки графика, хотя меня больше интересуют метки оси, а не точки графика. Однако мне было бы любопытно узнать, насколько похожи эти две задачи, и может ли это решение быть адаптировано для этой цели. Я не мог понять это самостоятельно.
Это мой первый пост, поэтому я не могу публиковать изображения, но этот код достигает того, что я хочу. Примечание: этот подход использует уродливый, уродливый взлом, который не является переносимым и неэффективным. Конечный сюжет, который я хочу снять, будет иметь грань (facet_grid
), а ось x- это фактор с разными изображениями на каждом тике оси, а не непрерывная переменная, поэтому я ищу более общее / надежное решение, которое не требует много проб и ошибок.
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()
3 ответа
Вот пример:
# 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())
Для одной панели довольно просто извлечь информацию из гроба оси x и заменить ее собственной. Я не уверен, как это можно распространить чисто на автоматические, многопанельные оси.
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)
Ниже приведено описание использования пользовательского гроба для меток осей.
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"))