Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tick marks misaligned with panel in ggplot2 [R]

Tags:

r

ggplot2

There always seems to be some small but noticeable offset between where tick marks end and where the panel starts.

minimum working example

This is more evident when axis limits are specified so that the axis ends on a tick (see above). e.g., On the y-axis, the highest tick is too high and the lowest tick is too low.

Code to reproduce:

library(ggplot2)
p <- 
  ggplot(mtcars,aes(mpg, wt)) + 
    geom_point() + 
    scale_y_continuous(limits=c(1,5), expand=c(0,0))

p <- p + theme_few()
p <- p + theme(axis.ticks=element_line(size=0.5),axis.ticks.length = unit(0.5, "cm")) # enlarged for clarity, although this happens regardless

How can I fix this?

Edit:

In using the accepted answer on my own data, I noticed this also changes how points at the axis extrema are clipped. Is there any way to correctly align ticks and the panel, but not change this behavior? I don't want to remove the points, just still hide the portions outside the panel.

minimum working example

like image 271
user2455117 Avatar asked Jan 18 '26 05:01

user2455117


1 Answers

it's not the position that's off, but the panel border that is being clipped,

library(ggplot2)
p <- ggplot(mtcars,aes(mpg, wt)) + geom_point() + scale_y_continuous(limits=c(1,5),expand=c(0,0))
p <- p + theme_bw()
p <- p + theme(axis.ticks=element_line(size=3),
               panel.border = element_rect(size = 3),
               axis.ticks.length = unit(0.5, "cm"))

g <- ggplotGrob(p)

g$layout$clip <- "off"
library(gridExtra)
grid.arrange(p, g, ncol=2)

enter image description here

Edit: The above observation wasn't meant to be a solution; as noted in the comments turning off the clipping for the whole panel is problematic for the points that leak out of the panel area. A possible workaround is to add a new grob to the gtable, e.g. by extracting it from panel and adding it on top without clipping.

library(ggplot2)
p <- ggplot(mtcars,aes(mpg, wt)) + geom_point(size=20) + scale_y_continuous(limits=c(1,5),expand=c(0,0))
p <- p + theme_bw()
p <- p + theme(axis.ticks=element_line(size=2),
               panel.border = element_rect(size = 2),
               axis.ticks.length = unit(0.5, "cm"))

g <- ggplotGrob(p)
panel_id <- g$layout$name == "panel"
border <- tail(g$grobs[panel_id][[1]][["children"]], 1)
g <- gtable::gtable_add_grob(g, border, 
                             t = min(g$layout$t[panel_id]),
                             l = min(g$layout$l[panel_id]),
                             name = "border",
                             clip = "off")

library(gridExtra)
grid.arrange(p, g, ncol=2)
like image 191
baptiste Avatar answered Jan 19 '26 19:01

baptiste



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!