X-axis label icons in R - ggplot2

(This is an extension for the question Icons as X-axis labels in R. It looks for a ggplot solution instead of plot. Since it ggplot

is grid- plot

based and plot-based, the approach is very different)

I would like to construct something like (from this article) where icons, in this case small graphs, are used as labels for labels.

enter image description here

The accepted answer from the original question:

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)  
}

      

enter image description here

How can we make a plot like this with ggplot ?

This is closer than what I am getting:

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)

      

enter image description here

+3


source to share


1 answer


This assembly is your attempt.

(I used set.seed(1)

to function rexp

, as well as changed the schedule for increasing the thickness of the edge: 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)

      

enter image description here

There will be a way to do it correctly / as per the excellent previous solution, but anyway ...

+1


source







All Articles