R/plot.R

Defines functions text.sf dummy_internal plot.sf

Documented in plot.sf text.sf

#' Plot simple features simply
#'
#' Overrides `sf::plot.sf` and wraps the call to `plot(st_geometry(x))`. When
#' working with spatial data it's often useful to create maps where we
#' overlay spatially coincident data in a plot.
#'
#' This is used so that plots aren't always facetted by all attributes, coloured
#' by them, or leaving the plot unusable for subsequent additional drawing. The
#' key feature is that we don't have to change our behaviour and good habits
#' depending on the format in use.
#'
#' @param x sf object (the data.frame one)
#' @param ... arguments passed to [sf::plot_sfc]
#' @return used for its side effects of creating a plot
#' @export
#' @examples
#' x <- read_sf(system.file("shape/nc.shp", package="sf"))
#' ## all we've changed is the plot command
#' plot(x)
#' ## we can overplot without format-specific acrobatics
#' plot(x[sample(1:nrow(x), 10), ], col = rainbow(10), add = TRUE)
#' abline(v = 34); axis(2)
#' @importFrom graphics plot
#' @importFrom sf st_geometry
plot.sf <- function(x, ...) {
 plot(sf::st_geometry(x), ...)
}

# just for read_sf
#' @importFrom tibble tibble
dummy_internal <- function() {
  tibble::tibble()
}


#' Label (text) simple features plots
#'
#' Plot labels from a sf object on a base plot.
#'
#' The first argument is an sf object and the 'labels' argument may be set manually, or if unset will
#' be taken as the first field (column) of data in the object. If there is no fields, the integer index
#' '1:nrow' will be used.
#'
#' Use '...' to control arguments of [text].
#'
#' To control which field is used to label, the easiest is to drop all columns but the first or to select
#' them with the one you want first in the usual ways of dplyr and so on.
#'
#' Labels are positioned with the centroid [sf::st_centroid] of the feature object (point, line, or area).
#'
#' There are many kinds of centroids, and many more ways of labelling things ... a short list of possibilities
#' that might make there way into this facility:
#' https://github.com/mdsumner/basf/issues/1#issuecomment-1030427651.
#' @export
#' @importFrom graphics text
#' @param x sf object
#' @inheritDotParams graphics::text
#' @return
#' @examples
#' x <- read_sf(system.file("shape/nc.shp", package="sf"))
#' plot(x)
#' text(x)  ## we get AREA
#' plot(x)
#' text(x["NAME"]) ## we want NAME
#' plot(x)
#' text(x, label = x$NAME)  # another way
#' ix <- sample(1:nrow(x), 8)
#' plot(x[ix, ])
#' plot(st_centroid(x[ix, ]), add = TRUE, pch = "+", cex = 0.8)
#' text(x[ix, 5], cex = 1.5, col = hcl.colors(8),  pos = 1:4, font = 2:5)
text.sf <- function(x, ...) {
  xy <- sf::st_coordinates(sf::st_centroid(x))[,1:2, drop = FALSE]
  args <- list(x = xy[,1, drop = TRUE], y = xy[,2, drop = TRUE], ...)
  ## just get lab, label, labels ...
  label <- args$lab
  if (is.null(label)) label <- sf::st_set_geometry(x, NULL)[[1L]]
  if (is.null(label)) label <- 1:nrow(xy)
  args$labels <- label
  args[["label"]] <- NULL  ## common aliases
  args[["lab"]] <- NULL
  do.call(text, args)
}
mdsumner/basf documentation built on Sept. 11, 2022, 1:08 p.m.