5

I'm trying to generate a "satisfactory" legend using ggplot2, but what frustrates me is the position of ticks (they are inside the legend key). Here is some code to show what I mean.

library(ggplot2)

ggplot(mtcars, aes(x = cyl, y = gear, fill = mpg)) +
  geom_tile() +
  coord_equal() +
  theme(legend.position = 'top')

What I get is below. The ticks are inside the legend key box. Ticks inside the legend key (I hate this)

Is there a way to put the ticks outside of the legend key box? Just like this legend (it look like they did this with ggplot2):

enter image description here

Any suggestion would be appreciated!!!

1 Answer 1

1

We can hack the unexported ggplot2:::guide_gengrob.colorbar function to simulate such an appearance.

Run

trace(ggplot2:::guide_gengrob.colorbar, edit = TRUE)

and replace the following lines (should be around line 26 or so)

if (guide$raster) {
  image <- switch(guide$direction, horizontal = t(guide$bar$colour), 
    vertical = rev(guide$bar$colour))
  grob.bar <- rasterGrob(image = image, width = barwidth, 
    height = barheight, default.units = "cm", gp = gpar(col = NA), 
    interpolate = TRUE)
}

with

if (guide$raster) {
  image <- switch(guide$direction, 
                  horizontal = with(guide$bar, 
                                    rbind(rep("white", length(colour)), 
                                          colour, 
                                          rep("white", length(colour)))), 
                  vertical = with(guide$bar, 
                                  cbind(rep("white", length(colour)), 
                                        rev(colour), 
                                        rep("white", length(colour)))))
  grob.bar <- rasterGrob(image = image, width = barwidth, 
    height = barheight, default.units = "cm", gp = gpar(col = NA), 
    interpolate = FALSE)
}

and click 'Save'.

Now the following code

p <- ggplot(mtcars, aes(x = cyl, y = gear, fill = mpg)) +
  geom_tile() +
  coord_equal() +
  scale_fill_continuous(guide = guide_colourbar(ticks.colour = "black"))

# works for both horizontal & vertical legends
p + theme(legend.position = 'top')
p + theme(legend.position = 'right')

produces

patched plots

To remove the effect at any point during the current R session, run

untrace(ggplot2:::guide_gengrob.colorbar)

(Note: this hack's effect won't persist across R sessions, and needs to be repeated each time this is desired.)

Explanation

The original image in the code is basically a vector of gradient colours, which is then used to create a raster grob object. In our modified version, we sandwich the vector with two vectors of repeated "white"'s, either horizontally or vertically, so that the visible gradient legend becomes narrower, and the ticks are no longer overlapping it.

We then change interpolate = TRUE to interpolate = FALSE in the raster grob's definition, so that we get a sharp transition from white to gradient bar and vice versa.

Lastly, tick colour is set as "black" in the ggplot code, so that the ticks can actually be seen against the white background.

1
  • Is this still the only way? I am looking to create the ticks outside of the key box but only in one direction, such as above the key box when horizontal or to the right when vertical. I was hoping to achieve this through some combination of theme options and/or guide_colourbar, but am coming up short.
    – Patrick
    Commented Feb 13 at 5:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.