ggplot2 icon indicating copy to clipboard operation
ggplot2 copied to clipboard

Annotate all facets with axis ticks and labels for fixed scales

Open clauswilke opened this issue 4 years ago • 9 comments

By default, interior facets are not drawn with axis ticks or labels.

library(ggplot2)

df <- data.frame(
  x = rnorm(900),
  y = rnorm(900),
  a = rep(letters[1:9], each = 10)
)

ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(vars(a))

However, if we set scales = "free", we do get per-facet axis ticks and labels, but now each facet also has its own scale range.

ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(vars(a), scales = "free")

I find that it's often desirable to have fixed scales but have each facet have its own axis annotations. This can currently be achieved by setting scales = "free" but then manually setting the scale limits.

ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(vars(a), scales = "free") +
  xlim(-4, 4) + ylim(-4, 4)

I think it would be a good idea to add an option that draws axis annotations for all facets even if scales are fixed. I routinely wish I had this option.

clauswilke avatar Jun 16 '20 05:06 clauswilke

I believe these lines are responsible for removing the axis annotations, and we would simply have to modify the if conditions to make this feature work.

https://github.com/tidyverse/ggplot2/blob/7e9e9d61b4406b21825d60f07821601a3157d656/R/facet-wrap.r#L289-L296

clauswilke avatar Jun 16 '20 06:06 clauswilke

Might be worth to look at what is possible with lemon : facet_rep_grid https://cran.r-project.org/web/packages/lemon/vignettes/facet-rep-labels.html

smouksassi avatar Jun 16 '20 06:06 smouksassi

Yeah, this is not something that is particularly hard to do. I've never found the need, personally, but if you feel for it we can add a switch

thomasp85 avatar Jun 16 '20 06:06 thomasp85

Yes, I think it'd be very useful. Of course I had hoped it would transfer over when calling ggplotly on the resulting object, and that's not the case. Oh well, one step at a time.

clauswilke avatar Jun 16 '20 14:06 clauswilke

I think the main challenge will be to come up with a good name for the argument. We currently have scales. Maybe axes? axes = "all" draws all, axes = "all_x" draws all for x, axes = "margins" only draws axes on the margins?

clauswilke avatar Jun 16 '20 21:06 clauswilke

additionally, it would be nice if 1) there was an option for the inner panels to have axes but only with ticks, without tick labels 2) all this functionality was available for facet_grid as well.

I've been using facet_rep_wrap and facet_rep_grid from the lemon package for this, but recent updates in grid and/or ggplot2 have partly broken it, see issue stefanedwards/lemon#24 , and it is not clear when it will be fixed.

Many academic journals I know of require figures without a background grid and without a frame around the figure. For figures with a single panel this style can be achieved with theme_classic, but figures with facets with this theme look odd without axes for the inner panels, e.g. compare:

 library(ggplot2); data(iris)
 ggplot(iris, aes(Petal.Length, Petal.Width)) + geom_point() + facet_wrap(~Species) + theme_classic() + theme(strip.background = element_blank()) 

with the same figure with axes for inner panels obtained with lemon:

 library(lemon)
 ggplot(iris, aes(Petal.Length, Petal.Width)) + geom_point() + facet_rep_wrap(~Species) + theme_classic() + theme(strip.background = element_blank())

sam81 avatar Jun 19 '20 10:06 sam81

Today I got a weird behaviour that seems related to this issue:

library(ggplot2)
ggplot(mpg, aes(displ, hwy)) + 
    geom_point()+ 
    facet_wrap(vars(class)) + 
    theme_classic() + 
    theme(strip.background=element_blank())

image

It seems to me more like a bug than other thing. Shouldn't axis be present in each facet? Previous comment by @sam81 helped me to solve the issue thanks to lemon library.

iago-pssjd avatar Sep 20 '21 22:09 iago-pssjd

I think the main challenge will be to come up with a good name for the argument. We currently have scales. Maybe axes? axes = "all" draws all, axes = "all_x" draws all for x, axes = "margins" only draws axes on the margins?

Just wanted to ask whether this could be implemented. As @sam81 mentioned, we need to plot the axis for each facet for many academic journals. For the naming, could that be integrated into the scales argument instead of new argument? Anyways, together with many academic authors, I would be grateful for an implementation as you see fit.

agilebean avatar Oct 06 '21 05:10 agilebean

For naming, how about something more descriptive like show_axes?

  • show_axes = "all"
  • show_axes = "all_x"
  • show_axes = "all_y"
  • show_axes = "margins"

steveharoz avatar Aug 21 '22 13:08 steveharoz