Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: make clipping configurable #2536

Closed
clauswilke opened this issue Apr 27, 2018 · 3 comments
Closed

Feature request: make clipping configurable #2536

clauswilke opened this issue Apr 27, 2018 · 3 comments

Comments

@clauswilke
Copy link
Member

@clauswilke clauswilke commented Apr 27, 2018

I frequently would like to be able to draw things that fall outside of the plot panel. This is currently not possible, as clipping is strictly enforced and not configurable. I think it would be nice if this could be switched on or off. First, as motivation, an example where it would be useful. Then my proposal of how it could be implemented.

Consider this plot:

mt_named <- data.frame(mtcars, name = row.names(mtcars))

p <- ggplot(mt_named, aes(mpg, reorder(name, mpg))) + 
  geom_point(size = 2.5, color = "#0072B2") +
  geom_text(aes(x = mpg + .5, label = name), hjust = 0, size = 3) +
  scale_y_discrete(name = NULL, breaks = NULL, expand = c(0, 1)) +
  theme_bw() +
  theme(panel.border = element_blank(),
        panel.grid.minor = element_blank(),
        axis.line.x = element_line(),
        plot.margin = margin(6, 45, 6, 6))
p

screen shot 2018-04-27 at 12 59 24 pm

The top-most text label is cut off because it extends beyond the plot area. To make it fit, I could extend the axis range, but that would extend the axis line as well. It looks more elegant to switch of clipping and have the text label extend outside of the plot area:

g <- ggplotGrob(p)
index <- grep("panel", g$layout$name)
g$layout$clip[index] = "off"
grid::grid.newpage()
grid::grid.draw(g)

screen shot 2018-04-27 at 1 00 14 pm

I would like to propose to address this by making clipping a feature of the coordinate system. For example, the above plot could be generated by something like this:

p + coord_cartesian(clip = "off")

This feature requires very minimal changes to the coord code and the facet layouting code. I'll see if I can put together a pull request implementing this.

@hadley
Copy link
Member

@hadley hadley commented Apr 27, 2018

This might require a few more downstream changes to make sure things are drawn in the correct order (i.e. labels go on top of the plot etc), but seems reasonable.

@hadley hadley added the wip label Apr 27, 2018
@clauswilke
Copy link
Member Author

@clauswilke clauswilke commented Apr 27, 2018

Not sure how realistic it is to change drawing order without causing all sorts of headaches. My vote would be to not touch that issue at this time but provide the clipping function for advanced users who can make use of it. Below, I'll mention some issues about drawing order for single-panel plots and multi-panel plots. In all cases, it comes down to the fact that panels are completely assembled before they are integrated into the rest of the plot.

1. Single-panel plots

Currently, the axes and axis lines are drawn after the panel is drawn and hence sit on top of the panel. This has bugged me at times, e.g. when the axis line sits on top of a bar in a bar plot. However, I think it needs to be this way. If we drew axis lines before we draw the panel, then the axis lines would be partially obscured by panels with opaque background, and that would be even worse. The correct drawing order would be to draw panel background, then panel grill, then axis lines, and then the geoms, but that would require a complete rethinking of the plot rendering process.

We can see that this issue arises from the documentation of Facet:

draw_panels: This is where the panels are assembled into a gtable object. The method recieves, among others, a list of grobs defining the content of each panel as generated by the Geoms and Coord objects. The responsibility of the method is to decorate the panels with axes and strips as needed, as well as position them relative to each other in a gtable. For some of the automatic functions to work correctly, each panel, axis, and strip grob name must be prefixed with "panel", "axis", and "strip" respectively.

In any case, in essentially all cases I can envision where I would want to switch clipping off, I wouldn't have an axis line overlap with the panel contents that sticks out of the panel area, so I think this is a minor issue.

2. Multi-panel plots.

Drawing order is a bigger problem for multi-panel plots, because panels that are drawn later will sit on top of panels that were drawn earlier. The only true fix would be to completely separate out the drawing order, and first draw all panel backgrounds, then all panel grills, then the first geom for all panels, then the second geom for all panels, and so on. At this time, I don't think this is worth the amount of work needed and the potential for breaking something. The alternative would be to simply continue to enforce clipping in faceted plots, but my attitude would be that it's always better to make things configurable than not.

However, if I'm missing something and there's an substantial improvement that can be had without rewriting all the rendering code then I'm happy to look into that.

clauswilke added a commit to wilkelab/ggplot2 that referenced this issue May 1, 2018
clauswilke added a commit to wilkelab/ggplot2 that referenced this issue May 1, 2018
@hadley hadley closed this in 0eadf1b May 1, 2018
@lock
Copy link

@lock lock bot commented Oct 29, 2018

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators Oct 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants