1#' Nudge points a fixed distance 2#' 3#' `position_nudge()` is generally useful for adjusting the position of 4#' items on discrete scales by a small amount. Nudging is built in to 5#' [geom_text()] because it's so useful for moving labels a small 6#' distance from what they're labelling. 7#' 8#' @family position adjustments 9#' @param x,y Amount of vertical and horizontal distance to move. 10#' @export 11#' @examples 12#' df <- data.frame( 13#' x = c(1,3,2,5), 14#' y = c("a","c","d","c") 15#' ) 16#' 17#' ggplot(df, aes(x, y)) + 18#' geom_point() + 19#' geom_text(aes(label = y)) 20#' 21#' ggplot(df, aes(x, y)) + 22#' geom_point() + 23#' geom_text(aes(label = y), position = position_nudge(y = -0.1)) 24#' 25#' # Or, in brief 26#' ggplot(df, aes(x, y)) + 27#' geom_point() + 28#' geom_text(aes(label = y), nudge_y = -0.1) 29position_nudge <- function(x = 0, y = 0) { 30 ggproto(NULL, PositionNudge, 31 x = x, 32 y = y 33 ) 34} 35 36#' @rdname ggplot2-ggproto 37#' @format NULL 38#' @usage NULL 39#' @export 40PositionNudge <- ggproto("PositionNudge", Position, 41 x = 0, 42 y = 0, 43 44 setup_params = function(self, data) { 45 list(x = self$x, y = self$y) 46 }, 47 48 compute_layer = function(self, data, params, layout) { 49 # transform only the dimensions for which non-zero nudging is requested 50 if (any(params$x != 0)) { 51 if (any(params$y != 0)) { 52 transform_position(data, function(x) x + params$x, function(y) y + params$y) 53 } else { 54 transform_position(data, function(x) x + params$x, NULL) 55 } 56 } else if (any(params$y != 0)) { 57 transform_position(data, NULL, function(y) y + params$y) 58 } else { 59 data # if both x and y are 0 we don't need to transform 60 } 61 } 62) 63