Skip to content

Commit 4ee7c65

Browse files
committed
Make graticule labeling configurable. Closes #2846.
1 parent 0fd9aa5 commit 4ee7c65

File tree

2 files changed

+93
-37
lines changed

2 files changed

+93
-37
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# ggplot2 3.0.0.9000
22

33
* `benchplot()` now uses tidy evaluation (@dpseidel, #2699).
4+
5+
* `coord_sf()` now takes a parameter `graticule_labeling` that can be used
6+
to specify which graticules to label on which side of the plot
7+
(@clauswilke, #2846).
48

59
* `fortify()` now displays a more informative error message for
610
`grouped_df()` objects when dplyr is not installed (@jimhester, #2822).

R/sf.R

Lines changed: 89 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ CoordSf <- ggproto("CoordSf", CoordCartesian,
349349
x_range = x_range,
350350
y_range = y_range,
351351
graticule = graticule,
352-
crs = params$crs
352+
crs = params$crs,
353+
graticule_labeling = self$graticule_labeling
353354
)
354355
},
355356

@@ -382,53 +383,97 @@ CoordSf <- ggproto("CoordSf", CoordCartesian,
382383
render_axis_h = function(self, panel_params, theme) {
383384
graticule <- panel_params$graticule
384385

385-
# horizontal axes label degrees east (meridians)
386-
# for the bottom side, graticule$plot12 tells us whether
387-
# a tick is needed or not
388-
ticks_bottom <- graticule[graticule$type == "E" & graticule$plot12, ]
389-
# for the top, we need to guess
390-
ticks_top <- graticule[graticule$type == "E" & graticule$y_end > 0.99, ]
391-
392-
list(
393-
top = guide_axis(
394-
ticks_top$x_end,
395-
ticks_top$degree_label,
386+
# top axis
387+
if (identical(panel_params$graticule_labeling$top, "E") ||
388+
identical(panel_params$graticule_labeling$top, "N")) {
389+
# we don't generally know which direction graticules run, so need to consider both
390+
ticks1 <- graticule[graticule$type == panel_params$graticule_labeling$top &
391+
graticule$y_start > 0.999, ]
392+
ticks2 <- graticule[graticule$type == panel_params$graticule_labeling$top &
393+
graticule$y_end > 0.999, ]
394+
tick_positions <- c(ticks1$x_start, ticks2$x_end)
395+
tick_labels <- c(ticks1$degree_label, ticks2$degree_label)
396+
397+
top <- guide_axis(
398+
tick_positions,
399+
tick_labels,
396400
position = "top",
397401
theme = theme
398-
),
399-
bottom = guide_axis(
400-
ticks_bottom$x_start,
401-
ticks_bottom$degree_label,
402+
)
403+
} else {
404+
top <- zeroGrob()
405+
}
406+
407+
# bottom axis
408+
if (identical(panel_params$graticule_labeling$bottom, "E") ||
409+
identical(panel_params$graticule_labeling$bottom, "N")) {
410+
# we don't generally know which direction graticules run, so need to consider both
411+
ticks1 <- graticule[graticule$type == panel_params$graticule_labeling$bottom &
412+
graticule$y_start < 0.001, ]
413+
ticks2 <- graticule[graticule$type == panel_params$graticule_labeling$bottom &
414+
graticule$y_end < 0.001, ]
415+
tick_positions <- c(ticks1$x_start, ticks2$x_end)
416+
tick_labels <- c(ticks1$degree_label, ticks2$degree_label)
417+
418+
bottom <- guide_axis(
419+
tick_positions,
420+
tick_labels,
402421
position = "bottom",
403422
theme = theme
404423
)
405-
)
424+
} else {
425+
bottom <- zeroGrob()
426+
}
427+
428+
list(top = top, bottom = bottom)
406429
},
407430

408431
render_axis_v = function(self, panel_params, theme) {
409432
graticule <- panel_params$graticule
410433

411-
# vertical axes label degrees north (parallels)
412-
# for the left side, graticule$plot12 tells us whether
413-
# a tick is needed or not
414-
ticks_left <- graticule[graticule$type == "N" & graticule$plot12, ]
415-
# for the right side, we need to guess
416-
ticks_right <- graticule[graticule$type == "N" & graticule$x_end > 0.99, ]
417-
418-
list(
419-
left = guide_axis(
420-
ticks_left$y_start,
421-
ticks_left$degree_label,
434+
# left axis
435+
if (identical(panel_params$graticule_labeling$left, "E") ||
436+
identical(panel_params$graticule_labeling$left, "N")) {
437+
# we don't generally know which direction graticules run, so need to consider both
438+
ticks1 <- graticule[graticule$type == panel_params$graticule_labeling$left &
439+
graticule$x_start < 0.001, ]
440+
ticks2 <- graticule[graticule$type == panel_params$graticule_labeling$left &
441+
graticule$x_end < 0.001, ]
442+
tick_positions <- c(ticks1$y_start, ticks2$y_end)
443+
tick_labels <- c(ticks1$degree_label, ticks2$degree_label)
444+
445+
left <- guide_axis(
446+
tick_positions,
447+
tick_labels,
422448
position = "left",
423449
theme = theme
424-
),
425-
right = guide_axis(
426-
ticks_right$y_end,
427-
ticks_right$degree_label,
450+
)
451+
} else {
452+
left <- zeroGrob()
453+
}
454+
455+
# right axis
456+
if (identical(panel_params$graticule_labeling$right, "E") ||
457+
identical(panel_params$graticule_labeling$right, "N")) {
458+
# we don't generally know which direction graticules run, so need to consider both
459+
ticks1 <- graticule[graticule$type == panel_params$graticule_labeling$right &
460+
graticule$x_start > 0.999, ]
461+
ticks2 <- graticule[graticule$type == panel_params$graticule_labeling$right &
462+
graticule$x_end > 0.999, ]
463+
tick_positions <- c(ticks1$y_start, ticks2$y_end)
464+
tick_labels <- c(ticks1$degree_label, ticks2$degree_label)
465+
466+
right <- guide_axis(
467+
tick_positions,
468+
tick_labels,
428469
position = "right",
429470
theme = theme
430471
)
431-
)
472+
} else {
473+
right <- zeroGrob()
474+
}
475+
476+
list(left = left, right = right)
432477
}
433478

434479
)
@@ -448,21 +493,28 @@ sf_rescale01_x <- function(x, range) {
448493
}
449494

450495

451-
#' @param crs Use this to select a specific CRS. If not specified, will
452-
#' use the CRS defined in the first layer.
496+
#' @param crs Use this to select a specific coordinate reference system (CRS).
497+
#' If not specified, will use the CRS defined in the first layer.
453498
#' @param datum CRS that provides datum to use when generating graticules
499+
#' @param graticule_labeling Named list of character values specifying which
500+
#' graticules (meridians or parallels) should be labeled on which side of the
501+
#' plot. Meridians are indicated by `"E"` (for East) and parallels by `"N"`
502+
#' (for North). Default is `list(top = NA, right = NA, bottom = "E",
503+
#' left = "N")` to label parallels on the left and meridians at the bottom.
454504
#' @param ndiscr number of segments to use for discretising graticule lines;
455505
#' try increasing this when graticules look unexpected
456506
#' @inheritParams coord_cartesian
457507
#' @export
458508
#' @rdname ggsf
459509
coord_sf <- function(xlim = NULL, ylim = NULL, expand = TRUE,
460-
crs = NULL, datum = sf::st_crs(4326), ndiscr = 100,
461-
default = FALSE) {
510+
crs = NULL, datum = sf::st_crs(4326),
511+
graticule_labeling = list(top = NA, right = NA, bottom = "E", left = "N"),
512+
ndiscr = 100, default = FALSE) {
462513
ggproto(NULL, CoordSf,
463514
limits = list(x = xlim, y = ylim),
464515
datum = datum,
465516
crs = crs,
517+
graticule_labeling = graticule_labeling,
466518
ndiscr = ndiscr,
467519
expand = expand,
468520
default = default

0 commit comments

Comments
 (0)