ggplot2 icon indicating copy to clipboard operation
ggplot2 copied to clipboard

`geom_sf()`: add support for `scale_x_continuous(n.breaks = )`

Open pat-s opened this issue 2 years ago • 9 comments

Currently this argument does not have an effect when using geom_sf().

library("ggplot2")
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
ggplot(nc) +
  geom_sf(aes(fill = AREA)) +
  scale_x_continuous(n.breaks = 2)

Created on 2021-09-18 by the reprex package (v2.0.1)

pat-s avatar Sep 18 '21 18:09 pat-s

@clauswilke do you have a rough idea of why coord_sf() behaves like this?

thomasp85 avatar Oct 28 '21 09:10 thomasp85

I'll take a look.

clauswilke avatar Oct 28 '21 12:10 clauswilke

Thanks... My guess is it comes down to sf, but you never know...

thomasp85 avatar Oct 28 '21 12:10 thomasp85

I think it's these two lines: https://github.com/tidyverse/ggplot2/blob/f5e01baec86469762a707e2ca8354378d0d31ab1/R/coord-sf.R#L226-L227

We're reading out the value of the breaks element directly instead of calling get_breaks(): https://github.com/tidyverse/ggplot2/blob/f5e01baec86469762a707e2ca8354378d0d31ab1/R/scale-.r#L636

But I don't fully understand how the other coords use this code. I believe they call guide_train.axis() which then calls get_breaks(): https://github.com/tidyverse/ggplot2/blob/f5e01baec86469762a707e2ca8354378d0d31ab1/R/guides-axis.r#L64-L67 but my problem is that I see how coord_cartesian() does this but not how coord_polar() does this. Yet things seem to work for coord_polar().

Maybe @paleolimbot can weigh in?

clauswilke avatar Nov 01 '21 01:11 clauswilke

I'm far removed from this to have a quick answer other than that I recall that the intention was to use the guide axis framework for the other Coord subclasses once the bugs had been ironed out for CoordCartesian. Perhaps this is a good time to do that for CoordSf? I'm nearly at a place where I could take that on but it will be a few weeks.

paleolimbot avatar Nov 01 '21 12:11 paleolimbot

But do I understand correctly that the guide axis framework is not needed to get the axis breaks right? So we could just fix the two lines in coord_sf() and be done with it?

I would suspect that coord_sf() is a particularly challenging coord to move to the guide axis framework, as it does a lot of non-standard things such as turning projected coordinates into long/lat values for labels.

clauswilke avatar Nov 01 '21 17:11 clauswilke

Yes, likely much easier! $get_breaks() is probably what should be used.

paleolimbot avatar Nov 01 '21 17:11 paleolimbot

I think the concern with using get_breaks() is that the default break computation used by sf might be much better. I don't have any evidence for this, so it might be worth doing a little spelunking in the sf code to figure out exactly what it's doing so we can make sure our defaults match.

hadley avatar Apr 19 '22 13:04 hadley

Some additional limitations:

  1. setting breaks = NULL does not remove gridlines or axis.
library(ggplot2)

nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

ggplot(nc) +
  geom_sf() +
  scale_x_continuous(breaks = NULL)

  1. Providing a function to breaks does not work.
ggplot(nc) +
  geom_sf() +
  scale_x_continuous(breaks = scales::breaks_width(1))
#> Error in min(lon): invalid 'type' (closure) of argument

Created on 2023-09-26 with reprex v2.0.2

teunbrand avatar Sep 26 '23 12:09 teunbrand