(This is an extension to the question Icons as x-axis labels in R. It looks for a ggplot solution instead of a plot one. Since ggplot
is based on grid and plot
is based on graphics, the approach is very different)
(这是问题图标在r中的x轴标签的扩展,它寻找的是一个ggplot解决方案,而不是一个plot解决方案。因为ggplot基于网格,而plot基于图形,所以方法非常不同)
I would like to plot something like this (from this paper) where icons, in this case small graphs, are used as tick labels.
我想画一些像这样的东西(从这篇论文)在这里,图标,在这个例子中,小图形,被用作标记标签。
The accepted answer from the original question is:
原问题的公认答案是:
library(igraph)
npoints <- 15
y <- rexp(npoints)
x <- seq(npoints)
# reserve some extra space on bottom margin (outer margin)
par(oma=c(3,0,0,0))
plot(y, xlab=NA, xaxt='n', pch=15, cex=2, col="red")
lines(y, col='red', lwd=2)
# graph numbers
x = 1:npoints
# add offset to first graph for centering
x[1] = x[1] + 0.4
x1 = grconvertX(x=x-0.4, from = 'user', to = 'ndc')
x2 = grconvertX(x=x+0.4, from = 'user', to = 'ndc')
for(i in x){
print(paste(i, x1[i], x2[i], sep='; '))
# remove plot margins (mar) around igraphs, so they appear bigger and
# `figure margins too large' error is avoided
par(fig=c(x1[i],x2[i],0,0.2), new=TRUE, mar=c(0,0,0,0))
plot(graph.ring(i), vertex.label=NA)
}
How can we make a similar plot using ggplot?
如何用ggplot制作一个类似的图呢?
This is the closer I get:
这是离我更近的距离:
library(ggplot2)
library(grImport)
library(igraph)
npoints <- 5
y <- rexp(npoints)
x <- seq(npoints)
pics <- vector(mode="list", length=npoints)
for(i in 1:npoints){
fileps <- paste0("motif",i,".ps")
filexml <- paste0("motif",i,".xml")
# Postscript file
postscript(file = fileps, fonts=c("serif", "Palatino"))
plot(graph.ring(i), vertex.label.family="serif", edge.label.family="Palatino")
dev.off()
# Convert to xml accessible for symbolsGrob
PostScriptTrace(fileps, filexml)
pics[i] <- readPicture(filexml)
}
xpos <- -0.20+x/npoints
my_g <- do.call("grobTree", Map(symbolsGrob, pics, x=xpos, y=0))
qplot(x, y, geom = c("line", "point")) + annotation_custom(my_g, xmin=-Inf, xmax=Inf, ymax=0.4, ymin=0.3)
1 个解决方案
#1
1
This builds of your attempt.
这是你的尝试。
(I used set.seed(1)
before the rexp
function and also tweaked the graph to increase the edge thickness: plot(graph.ring(i), vertex.label=NA, edge.width=30)
)
(我在rexp函数之前使用了set.seed(1),并对图形进行了修改,以增加边缘厚度:plot(graph.ring(I)、顶点。标签= NA,edge.width = 30))
Continuing from above:
继续从上面:
# Initial plot
p <- qplot(x, y, geom = c("line", "point"))
# Use the plot to get the x-positions of the labels
g <- ggplotGrob(p)
xpos <- g$grobs[[grep("axis-b", g$layout$name)]]$children[[2]]$grobs[[2]]$x
# Create grob tree
my_g <- do.call("grobTree", Map(symbolsGrob, pics, x=xpos, y=0.5))
# Make second plot
# Add extra space under the plot for the images
# Remove x-axis details
# Note the annotation is below the lower y-axis limit
# The limits were selected by inspection
p2 <- p + annotation_custom(my_g, xmin=-Inf, xmax=Inf, ymax=-0.1, ymin=-0.2) +
theme(axis.text.x = element_blank(),
plot.margin=unit(c(1,1,2,1), "cm"))
# remove clipping so the images render
g <- ggplotGrob(p2)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.newpage()
grid.draw(g)
There will be a way to do this properly / in line with the lovely previous solution, but anyways ...
有一种方法可以很好地做到这一点/与前面那个可爱的解决方案相一致,但是不管怎样……
#1
1
This builds of your attempt.
这是你的尝试。
(I used set.seed(1)
before the rexp
function and also tweaked the graph to increase the edge thickness: plot(graph.ring(i), vertex.label=NA, edge.width=30)
)
(我在rexp函数之前使用了set.seed(1),并对图形进行了修改,以增加边缘厚度:plot(graph.ring(I)、顶点。标签= NA,edge.width = 30))
Continuing from above:
继续从上面:
# Initial plot
p <- qplot(x, y, geom = c("line", "point"))
# Use the plot to get the x-positions of the labels
g <- ggplotGrob(p)
xpos <- g$grobs[[grep("axis-b", g$layout$name)]]$children[[2]]$grobs[[2]]$x
# Create grob tree
my_g <- do.call("grobTree", Map(symbolsGrob, pics, x=xpos, y=0.5))
# Make second plot
# Add extra space under the plot for the images
# Remove x-axis details
# Note the annotation is below the lower y-axis limit
# The limits were selected by inspection
p2 <- p + annotation_custom(my_g, xmin=-Inf, xmax=Inf, ymax=-0.1, ymin=-0.2) +
theme(axis.text.x = element_blank(),
plot.margin=unit(c(1,1,2,1), "cm"))
# remove clipping so the images render
g <- ggplotGrob(p2)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.newpage()
grid.draw(g)
There will be a way to do this properly / in line with the lovely previous solution, but anyways ...
有一种方法可以很好地做到这一点/与前面那个可爱的解决方案相一致,但是不管怎样……