(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)
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?
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)
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)
)
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 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With