Skip to content

Instantly share code, notes, and snippets.

@yeedle
Forked from jonocarroll/add_images_as_xlabels.R
Created March 6, 2017 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yeedle/ea4c0e44f04dce55e682fafacefb08b8 to your computer and use it in GitHub Desktop.
Save yeedle/ea4c0e44f04dce55e682fafacefb08b8 to your computer and use it in GitHub Desktop.
Replace categorical x-axis labels with images
#' Replace categorical x-axis labels with images
#'
#' Pipe a ggplot2 graph (with categorical x-axis) into this function with the argument of a list of
#' pictures (e.g. loaded via readImage) and it builds a new grob with the x-axis categories
#' now labelled by the images. Solves a problem that you perhaps shouldn't have.
#'
#' @author J. Carroll, \email{jono@@jcarroll.com.au}
#' @references \url{http://stackoverflow.com/questions/29939447/icons-as-x-axis-labels-in-r-ggplot2}
#'
#' @param g ggplot graph with categorical x axis
#' @param pics ordered list of pictures to place along x-axis
#'
#' @return NULL (called for the side-effect of producing a new grob with images for x-axis labels)
#'
#' @import grid
#' @import ggplot2
#'
#' @export
#'
#' @example
#' \dontrun{ggplot(data, aes(x=factor(x),y=y)) + geom_point() %>% add_images_as_xlabels(pics)}
#'
add_images_as_xlabels <- function(g, pics) {
## ensure that the input is a ggplot
if(!inherits(g, "ggplot")) stop("Requires a valid ggplot to attach images to.")
## extract the components of the ggplot
gb <- ggplot_build(gg)
xpos <- gb$panel$ranges[[1]]$x.major
yrng <- gb$panel$ranges[[1]]$y.range
## ensure that the number of pictures to use for labels
## matches the number of x categories
if(length(xpos) != length(pics)) stop("Detected a different number of pictures to x categories")
## create a new grob of the images aligned to the x-axis
## at the categorical x positions
my_g <- do.call("grobTree", Map(rasterGrob, pics, x=xpos, y=0))
## annotate the original ggplot with the new grob
gg <- gg + annotation_custom(my_g,
xmin = -Inf,
xmax = Inf,
ymax = yrng[1] + 0.25*(yrng[2]-yrng[1])/npoints,
ymin = yrng[1] - 0.50*(yrng[2]-yrng[1])/npoints)
## turn off clipping to allow plotting outside of the plot area
gg2 <- ggplotGrob(gg)
gg2$layout$clip[gg2$layout$name=="panel"] <- "off"
## produce the final, combined grob
grid.newpage()
grid.draw(gg2)
return(invisible(NULL))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment