tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.46k stars 2.02k forks source link

coord_sf() drops axis labels if graticules don't extend all the way to the plot boundary #2985

Open clauswilke opened 5 years ago

clauswilke commented 5 years ago

In ggplot2 3.1.0, coord_sf() drops axis labels if graticules don't extend all the way to the plot boundary. This is a regression from 3.0.0. A reprex follows.

library(ggplot2)

world <- sf::st_as_sf(rworldmap::getMap(resolution = "low"))
ggplot(world) + geom_sf() + theme_bw() + coord_sf()

ggplot(world) + geom_sf() + theme_bw() + coord_sf(expand = FALSE)

Created on 2018-11-08 by the reprex package (v0.2.1)

This bug was introduced by me when I wrote code such as the following, to calculate intersection points between the graticules and the plot boundaries: https://github.com/tidyverse/ggplot2/blob/15ddc222d197f1d4fa596ddb930d46f4819d8db0/R/sf.R#L592

I did not consider that the plot range could extend beyond the physical limits of the earth. I'll have to ponder what the options are. One option might be to make the tolerance configurable. (I hardcoded 0.001.) Another option might be to base the tolerance on the expansion factors used for the x and y scales.

hadley commented 5 years ago

Alternatively, should we prohibit plot ranges that are outside of the limits of the earth?

clauswilke commented 5 years ago

I don't think that's a feasible approach. We want to be able to make plots such as these:

library(ggplot2)

world <- sf::st_as_sf(rworldmap::getMap(resolution = "low"))
ggplot(world) + geom_sf() + theme_bw() +
  coord_sf(crs = "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000")


ggplot(world) + geom_sf() + theme_bw() + 
  coord_sf(crs = "+proj=robin")

Created on 2018-11-09 by the reprex package (v0.2.1)

On further reflection, it's not entirely clear to me what the right approach is. In the general case, if the graticule lines don't intersect with the plot boundary, we don't know where to place the ticks. It only works out in the longlat projection because the lines are perfectly horizontal/vertical. On the flip side, it would be nice to place labels at arbitrary positions along the axes, at least manually, and that isn't possible currently.

I noticed the old behavior here: https://www.r-spatial.org/r/2018/10/25/ggplot2-sf.html Notice how the longlat projection has labels but the Lambert Azimuthal Equal-Area projection does not. So the old behavior also had some inconsistencies.

hadley commented 5 years ago

Ah good point. I guess the ideal behaviour is to project out the graticule lines to where they would intersect with the plot, but I don't see how we'd have enough information to do that (or what that even really means when the graticules are not reasonable straight lines)

thomasp85 commented 5 years ago

projection could also result in some weird placements for highly non-linear graticules... and alternative could be to provide an annotation function for adding graticule labels for the cases where they are not drawn by the axes

teunbrand commented 9 months ago

Hi @edzer, do you happen to know if there is a reliable way to get an 'outline' of sf geometries that encompasses the graticule? I think tick mark positions and labels can already be extracted from the graticule, but I'm unsure how to connect these ticks to form a sort of curved axis.