From 7a45400f06665be3759230454bd52bdac6c8c7fc Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Fri, 8 Apr 2016 14:18:06 +0200 Subject: [PATCH] Add annotate_textp Annotate a plot with text using plot coordinates instead of data coordinates. Originally from https://stackoverflow.com/questions/22488563/ggplot2-annotate-layer-position-in-r/22500252#22500252 by Rosen Matev --- DESCRIPTION | 2 ++ NAMESPACE | 1 + R/annotate_textp.r | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ man/annotate_textp.Rd | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 R/annotate_textp.r create mode 100644 man/annotate_textp.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 5446ab5..3eb7492 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,6 +7,7 @@ Authors@R: c( person("Bob", "Rudis", email = "bob@rudis.net", role = c("aut", "cre")), person("Ben", "Bolder", role = c("aut", "ctb")), person("Jan", "Schulz", role = c("aut", "ctb")), + person("Rosen", "Matev", role="ctb", comment="Original annotate_textp implementation on stackoverflow"), person("Ingemar", role="dtc", comment="Pokémon javascript color palette"), person("ProPublica", role="dtc", comment="StateFace font") ) @@ -56,6 +57,7 @@ Collate: 'geom_encircle.r' 'geom_table.r' 'geom_xspline.r' + 'annotate_textp.r' 'geom_xspline2.r' 'ggalt-package.r' 'grob_absolute.r' diff --git a/NAMESPACE b/NAMESPACE index 709d9ae..372c84c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,6 +20,7 @@ export(StatAsh) export(StatBkde) export(StatBkde2d) export(StatXspline) +export(annotate_textp) export(byte_format) export(bytes) export(coord_proj) diff --git a/R/annotate_textp.r b/R/annotate_textp.r new file mode 100644 index 0000000..b3cd976 --- /dev/null +++ b/R/annotate_textp.r @@ -0,0 +1,61 @@ +#' Text annotations in plot coordinate system +#' +#' Annotates the plot with text. Compared to \code{annotate("text",...)}, the +#' placement of the annotations is specified in plot coordinates (from 0 to 1) +#' instead of data coordinates. +#' +#' @param label text annotation to be placed on the plot +#' @param x,y positions of the individual annotations, in plot coordinates +#' (0..1) instead of data coordinates! +#' @param facets facet positions of the individual annotations +#' @param hjust,vjust horizontal and vertical justification of the text relative +#' to the bounding box +#' @param color, alpha, family, size, fontface, lineheight font properties +#' @param box_just placement of the bounding box for the text relative to x,y +#' coordinates. Per default, the box is placed to the center of the plot. Be +#' aware that parts of the box which are outside of the visible region of the +#' plot will not be shown. +#' @param margin margins of the bounding box +#' @examples +#' p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +#' p <- p + geom_smooth(method = "lm", se = FALSE) +#' p + annotate_textp(x = 0.9, y = 0.35, label="A relative linear\nrelationship", hjust=1, color="red") +#' @export +annotate_textp <- function(label, x, y, facets=NULL, hjust=0, vjust=0, color='black', alpha=NA, + family=theme_get()$text$family, size=theme_get()$text$size, fontface=1, lineheight=1.0, + box_just=ifelse(c(x,y)<0.5,0,1), margin=unit(size/2, 'pt')) { + # based on https://stackoverflow.com/questions/22488563/ggplot2-annotate-layer-position-in-r/22500252#22500252 + if (x < 0 || x > 1){ + stop("x values must be in plot coordinates (between 0 and 1)") + } + if (y < 0 || y > 1){ + stop("y values must be in plot coordinates (between 0 and 1)") + } + x <- scales::squish_infinite(x) + y <- scales::squish_infinite(y) + data <- if (is.null(facets)) data.frame(x=NA) else data.frame(x=NA, facets) + + tg <- grid::textGrob( + label, x=0, y=0, hjust=hjust, vjust=vjust, + gp=grid::gpar(col=alpha(color, alpha), fontsize=size, fontfamily=family, fontface=fontface, lineheight=lineheight) + ) + ts <- grid::unit.c(grid::grobWidth(tg), grid::grobHeight(tg)) + vp <- grid::viewport(x=x, y=y, width=ts[1], height=ts[2], just=box_just) + tg <- grid::editGrob(tg, x=ts[1]*hjust, y=ts[2]*vjust, vp=vp) + inner <- grid::grobTree(tg, vp=grid::viewport(width=unit(1, 'npc')-margin*2, height=unit(1, 'npc')-margin*2)) + + layer( + data = NULL, + stat = StatIdentity, + position = PositionIdentity, + geom = GeomCustomAnn, + inherit.aes = TRUE, + params = list( + grob=grid::grobTree(inner), + xmin=-Inf, + xmax=Inf, + ymin=-Inf, + ymax=Inf + ) + ) +} \ No newline at end of file diff --git a/man/annotate_textp.Rd b/man/annotate_textp.Rd new file mode 100644 index 0000000..3cdbfee --- /dev/null +++ b/man/annotate_textp.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/annotate_textp.r +\name{annotate_textp} +\alias{annotate_textp} +\title{Text annotations in plot coordinate system} +\usage{ +annotate_textp(label, x, y, facets = NULL, hjust = 0, vjust = 0, + color = "black", alpha = NA, family = theme_get()$text$family, + size = theme_get()$text$size, fontface = 1, lineheight = 1, + box_just = ifelse(c(x, y) < 0.5, 0, 1), margin = unit(size/2, "pt")) +} +\arguments{ +\item{label}{text annotation to be placed on the plot} + +\item{x, y}{positions of the individual annotations, in plot coordinates +(0..1) instead of data coordinates!} + +\item{facets}{facet positions of the individual annotations} + +\item{hjust, vjust}{horizontal and vertical justification of the text relative +to the bounding box} + +\item{color, }{alpha, family, size, fontface, lineheight font properties} + +\item{box_just}{placement of the bounding box for the text relative to x,y +coordinates. Per default, the box is placed to the center of the plot. Be +aware that parts of the box which are outside of the visible region of the +plot will not be shown.} + +\item{margin}{margins of the bounding box} +} +\description{ +Annotates the plot with text. Compared to \code{annotate("text",...)}, the +placement of the annotations is specified in plot coordinates (from 0 to 1) +instead of data coordinates. +} +\examples{ +p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() +p <- p + geom_smooth(method = "lm", se = FALSE) +p + annotate_textp(x = 0.9, y = 0.35, label="A relative linear\\nrelationship", hjust=1, color="red") +} +