From 6c97cbc4c977e1f53cd1668632061ecab4c03801 Mon Sep 17 00:00:00 2001 From: William Gearty Date: Thu, 16 Nov 2023 10:52:00 -0500 Subject: [PATCH 1/5] Change color/fill defaults and behavior when only color is specified; update vignettes to use fill instead of color --- R/add_phylopic.r | 10 +- R/add_phylopic_base.r | 17 ++-- R/geom_phylopic.R | 18 ++-- man/add_phylopic.Rd | 12 +-- man/add_phylopic_base.Rd | 8 +- man/geom_phylopic.Rd | 26 +++-- .../add_phylopic/phylopic-in-background.svg | 30 +++--- .../add_phylopic/phylopics-on-top-of-plot.svg | 76 +++++++------- .../phylopic-in-background.svg | 4 +- .../phylopics-on-top-of-plot.svg | 96 +++++++++--------- .../_snaps/geom_phylopic/geom-phylopic.svg | 40 ++++---- .../phylopic-key-glyph-with-img.svg | 10 +- .../phylopic-key-glyph-with-larger-glyphs.svg | 12 +-- .../phylopic-key-glyph-with-uuid.svg | 10 +- .../geom_phylopic/phylopic-key-glyph.svg | 12 +-- tests/testthat/test-add_phylopic.R | 5 +- tests/testthat/test-add_phylopic_base.R | 7 +- vignettes/a-getting-started.Rmd | 13 ++- vignettes/a-getting-started.Rmd.orig | 11 +- vignettes/b-advanced-ggplot.Rmd | 23 +++-- vignettes/b-advanced-ggplot.Rmd.orig | 21 ++-- vignettes/base-geog-plot-1-1.png | Bin 29245 -> 29302 bytes vignettes/base-geog-plot-2-1.png | Bin 30075 -> 30767 bytes vignettes/base-penguin-plot-2-1.png | Bin 27087 -> 27114 bytes vignettes/base-penguin-plot-3-1.png | Bin 33169 -> 34433 bytes vignettes/base-penguin-plot-4-1.png | Bin 32488 -> 33777 bytes vignettes/base-penguin-plot-5-1.png | Bin 34208 -> 39726 bytes vignettes/base-phylo-plot-3-1.png | Bin 20467 -> 20705 bytes vignettes/base-phylo-plot-4-1.png | Bin 20677 -> 20938 bytes vignettes/c-advanced-base.Rmd | 16 +-- vignettes/c-advanced-base.Rmd.orig | 14 +-- vignettes/ggplot-geog-plot-1-1.png | Bin 30434 -> 30415 bytes vignettes/ggplot-geog-plot-2-1.png | Bin 30245 -> 30051 bytes vignettes/ggplot-geog-plot-3-1.png | Bin 31423 -> 31249 bytes vignettes/ggplot-penguin-plot-2-1.png | Bin 37752 -> 37773 bytes vignettes/ggplot-penguin-plot-3-1.png | Bin 44226 -> 46033 bytes vignettes/ggplot-penguin-plot-4-1.png | Bin 42735 -> 43815 bytes vignettes/ggplot-penguin-plot-5-1.png | Bin 45457 -> 46692 bytes vignettes/ggplot-penguin-plot-6-1.png | Bin 45496 -> 46806 bytes vignettes/ggplot-phylo-plot-3-1.png | Bin 59407 -> 59940 bytes vignettes/ggplot-phylo-plot-4-1.png | Bin 59870 -> 60361 bytes vignettes/intro-base-plot-1.png | Bin 11932 -> 12001 bytes vignettes/intro-ggplot-plot-1.png | Bin 21554 -> 21668 bytes vignettes/intro-transform-plot-1.png | Bin 20859 -> 21130 bytes 44 files changed, 247 insertions(+), 244 deletions(-) diff --git a/R/add_phylopic.r b/R/add_phylopic.r index 8dbf5c8..4ca2615 100644 --- a/R/add_phylopic.r +++ b/R/add_phylopic.r @@ -24,8 +24,8 @@ #' (usually the same as "transparent"). #' @param fill \code{character}. Color of silhouette. If "original" is #' specified, the original color of the silhouette will be used (usually the -#' same as "black"). If `color` is specified and `fill` is NA the outline and -#' fill color will be the same. +#' same as "black"). If `color` is specified and `fill` is NA, `color` will be +#' used as the fill color (for backwards compatibility). #' @param horizontal \code{logical}. Should the silhouette be flipped #' horizontally? #' @param vertical \code{logical}. Should the silhouette be flipped vertically? @@ -68,7 +68,7 @@ #' angle <- runif(10, 0, 360) #' hor <- sample(c(TRUE, FALSE), 10, TRUE) #' ver <- sample(c(TRUE, FALSE), 10, TRUE) -#' cols <- sample(c("black", "darkorange", "grey42", "white"), 10, +#' fills <- sample(c("black", "darkorange", "grey42", "white"), 10, #' replace = TRUE) #' alpha <- runif(10, 0.3, 1) #' @@ -76,12 +76,12 @@ #' geom_blank() + #' add_phylopic(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", #' x = posx, y = posy, ysize = sizey, -#' color = cols, alpha = alpha, angle = angle, +#' fill = fills, alpha = alpha, angle = angle, #' horizontal = hor, vertical = ver) #' p + ggtitle("R Cat Herd!!") add_phylopic <- function(img = NULL, name = NULL, uuid = NULL, filter = NULL, x, y, ysize = Inf, - alpha = 1, color = "black", fill = NA, + alpha = 1, color = NA, fill = "black", horizontal = FALSE, vertical = FALSE, angle = 0, remove_background = TRUE, verbose = FALSE) { if (all(sapply(list(img, name, uuid), is.null))) { diff --git a/R/add_phylopic_base.r b/R/add_phylopic_base.r index 5acf4ff..709eec1 100644 --- a/R/add_phylopic_base.r +++ b/R/add_phylopic_base.r @@ -26,8 +26,8 @@ #' (usually the same as "transparent"). #' @param fill \code{character}. Color of silhouette. If "original" is #' specified, the original color of the silhouette will be used (usually the -#' same as "black"). If `color` is specified and `fill` is NA the outline and -#' fill color will be the same. +#' same as "black"). If `color` is specified and `fill` is NA, `color` will be +#' used as the fill color (for backwards compatibility). #' @param horizontal \code{logical}. Should the silhouette be flipped #' horizontally? #' @param vertical \code{logical}. Should the silhouette be flipped vertically? @@ -75,13 +75,13 @@ #' angle <- runif(10, 0, 360) #' hor <- sample(c(TRUE, FALSE), 10, TRUE) #' ver <- sample(c(TRUE, FALSE), 10, TRUE) -#' cols <- sample(c("black", "darkorange", "grey42", "white"), 10, +#' fills <- sample(c("black", "darkorange", "grey42", "white"), 10, #' replace = TRUE) #' #' plot(posx, posy, type = "n", main = "A cat herd") #' add_phylopic_base(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", #' x = posx, y = posy, ysize = size, -#' color = cols, angle = angle, +#' fill = fills, angle = angle, #' horizontal = hor, vertical = ver) #' #' # Example using a cat background @@ -190,9 +190,12 @@ add_phylopic_base <- function(img = NULL, name = NULL, uuid = NULL, if (angle != 0) img <- rotate_phylopic(img, angle) # recolor if necessary - color <- if (is.na(color) || color == "original") NULL else color - if (is.na(fill)) fill <- color - fill <- if (fill == "original") NULL else fill + if (is.na(color) || color == "original") color <- NULL + if (is.na(fill)) { + fill <- color + color <- NULL + } + if (fill == "original") fill <- NULL img <- recolor_phylopic(img, alpha, color, fill, remove_background) # grobify and plot diff --git a/R/geom_phylopic.R b/R/geom_phylopic.R index 5615548..de63a48 100644 --- a/R/geom_phylopic.R +++ b/R/geom_phylopic.R @@ -14,11 +14,11 @@ phylopic_env <- new.env() #' specifies the height of the silhouettes in the units of the y axis. The #' aspect ratio of the silhouettes will always be maintained. #' -#' The `color` (default: "black"), `fill` (default: NA), and `alpha` (default: -#' 1) aesthetics can be used to change the outline color, fill color, and -#' transparency (outline and fill) of the silhouettes, respectively. If -#' `color` is specified and `fill` is NA the outline and fill color will be -#' the same. If "original" is specified for the `color` aesthetic, the +#' The `color` (default: NA), `fill` (default: "black"), and `alpha` ( +#' default: 1) aesthetics can be used to change the outline color, fill color, +#' and transparency (outline and fill) of the silhouettes, respectively. If +#' `color` is specified and `fill` is NA `color` will be used as the fill +#' color (for backwards compatibility). If "original" is specified for the `color` aesthetic, the #' original color of the silhouette outline will be used (usually the same as #' "transparent"). If "original" is specified for the `fill` aesthetic, the #' original color of the silhouette body will be used (usually the same as @@ -74,7 +74,7 @@ phylopic_env <- new.env() #' name = c("Felis silvestris catus", "Odobenus rosmarus")) #' ggplot(df) + #' geom_phylopic(aes(x = x, y = y, name = name), -#' color = "purple", size = 10) + +#' fill = "purple", size = 10) + #' facet_wrap(~name) + #' coord_cartesian(xlim = c(1,6), ylim = c(5, 30)) #' } @@ -120,11 +120,10 @@ geom_phylopic <- function(mapping = NULL, data = NULL, #' @importFrom grid gTree gList nullGrob GeomPhylopic <- ggproto("GeomPhylopic", Geom, required_aes = c("x", "y"), - non_missing_aes = c("size", "alpha", "color", + non_missing_aes = c("size", "alpha", "color", "fill", "horizontal", "vertical", "angle"), optional_aes = c("img", "name", "uuid"), # one and only one of these - default_aes = aes(size = 6, alpha = 1, - color = "black", fill = NA, + default_aes = aes(size = 6, alpha = 1, color = NA, fill = "black", horizontal = FALSE, vertical = FALSE, angle = 0), extra_params = c("na.rm", "remove_background", "verbose", "filter"), setup_data = function(data, params) { @@ -212,6 +211,7 @@ GeomPhylopic <- ggproto("GeomPhylopic", Geom, data <- ggproto_parent(Geom, self)$use_defaults(data, params, modifiers) if (col_fill[1] && !col_fill[2]) { data$fill <- data$colour + data$colour <- NA } data }, diff --git a/man/add_phylopic.Rd b/man/add_phylopic.Rd index 6d30d32..06a97f3 100644 --- a/man/add_phylopic.Rd +++ b/man/add_phylopic.Rd @@ -13,8 +13,8 @@ add_phylopic( y, ysize = Inf, alpha = 1, - color = "black", - fill = NA, + color = NA, + fill = "black", horizontal = FALSE, vertical = FALSE, angle = 0, @@ -53,8 +53,8 @@ NA is specified, the original color of the silhouette outline will be used \item{fill}{\code{character}. Color of silhouette. If "original" is specified, the original color of the silhouette will be used (usually the -same as "black"). If \code{color} is specified and \code{fill} is NA the outline and -fill color will be the same.} +same as "black"). If \code{color} is specified and \code{fill} is NA, \code{color} will be +used as the fill color (for backwards compatibility).} \item{horizontal}{\code{logical}. Should the silhouette be flipped horizontally?} @@ -107,7 +107,7 @@ sizey <- runif(10, 0.4, 2) angle <- runif(10, 0, 360) hor <- sample(c(TRUE, FALSE), 10, TRUE) ver <- sample(c(TRUE, FALSE), 10, TRUE) -cols <- sample(c("black", "darkorange", "grey42", "white"), 10, +fills <- sample(c("black", "darkorange", "grey42", "white"), 10, replace = TRUE) alpha <- runif(10, 0.3, 1) @@ -115,7 +115,7 @@ p <- ggplot(data.frame(cat.x = posx, cat.y = posy), aes(cat.x, cat.y)) + geom_blank() + add_phylopic(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", x = posx, y = posy, ysize = sizey, - color = cols, alpha = alpha, angle = angle, + fill = fills, alpha = alpha, angle = angle, horizontal = hor, vertical = ver) p + ggtitle("R Cat Herd!!") } diff --git a/man/add_phylopic_base.Rd b/man/add_phylopic_base.Rd index 7c9b2d9..1dc7965 100644 --- a/man/add_phylopic_base.Rd +++ b/man/add_phylopic_base.Rd @@ -55,8 +55,8 @@ NA is specified, the original color of the silhouette outline will be used \item{fill}{\code{character}. Color of silhouette. If "original" is specified, the original color of the silhouette will be used (usually the -same as "black"). If \code{color} is specified and \code{fill} is NA the outline and -fill color will be the same.} +same as "black"). If \code{color} is specified and \code{fill} is NA, \code{color} will be +used as the fill color (for backwards compatibility).} \item{horizontal}{\code{logical}. Should the silhouette be flipped horizontally?} @@ -111,13 +111,13 @@ size <- runif(10, 0.1, 0.3) angle <- runif(10, 0, 360) hor <- sample(c(TRUE, FALSE), 10, TRUE) ver <- sample(c(TRUE, FALSE), 10, TRUE) -cols <- sample(c("black", "darkorange", "grey42", "white"), 10, +fills <- sample(c("black", "darkorange", "grey42", "white"), 10, replace = TRUE) plot(posx, posy, type = "n", main = "A cat herd") add_phylopic_base(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", x = posx, y = posy, ysize = size, - color = cols, angle = angle, + fill = fills, angle = angle, horizontal = hor, vertical = ver) # Example using a cat background diff --git a/man/geom_phylopic.Rd b/man/geom_phylopic.Rd index 5307862..af10fcb 100644 --- a/man/geom_phylopic.Rd +++ b/man/geom_phylopic.Rd @@ -76,8 +76,8 @@ used silhouette(s) be printed to the console (see \code{\link[=get_attribution]{ \item{filter}{\code{character}. Filter by usage license if using the \code{name} aesthetic. Use "by" to limit results to images which do not require attribution, "nc" for images which allows commercial usage, and "sa" for -images without a ShareAlike clause. The user can also combine these -filters as a vector.} +images without a ShareAlike clause. The user can also combine these filters +as a vector.} } \description{ This geom acts like \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}, except that the specified @@ -93,17 +93,15 @@ silhouettes at specified positions on the plot. The \code{size} aesthetic specifies the height of the silhouettes in the units of the y axis. The aspect ratio of the silhouettes will always be maintained. -The \code{color} (default: "black"), \code{fill} (default: NA), and \code{alpha} (default: -\enumerate{ -\item aesthetics can be used to change the outline color, fill color, and -transparency (outline and fill) of the silhouettes, respectively. If -\code{color} is specified and \code{fill} is NA the outline and fill color will be -the same. If "original" is specified for the \code{color} aesthetic, the -original color of the silhouette outline will be used (usually the same as -"transparent"). If "original" is specified for the \code{fill} aesthetic, the -original color of the silhouette body will be used (usually the same as -"black"). -} +The \code{color} (default: NA), \code{fill} (default: "black"), and \code{alpha} ( +default: 1) aesthetics can be used to change the outline color, fill color, +and transparency (outline and fill) of the silhouettes, respectively. If +\code{color} is specified and \code{fill} is NA \code{color} will be used as the fill +color (for backwards compatibility). If "original" is specified for the +\code{color} aesthetic, the original color of the silhouette outline will be +used (usually the same as "transparent"). If "original" is specified for +the \code{fill} aesthetic, the original color of the silhouette body will be +used (usually the same as "black"). The \code{horizontal} and \code{vertical} aesthetics can be used to flip the silhouettes. The \code{angle} aesthetic can be used to rotate the silhouettes. @@ -140,7 +138,7 @@ df <- data.frame(x = c(2, 4), y = c(10, 20), name = c("Felis silvestris catus", "Odobenus rosmarus")) ggplot(df) + geom_phylopic(aes(x = x, y = y, name = name), - color = "purple", size = 10) + + fill = "purple", size = 10) + facet_wrap(~name) + coord_cartesian(xlim = c(1,6), ylim = c(5, 30)) } diff --git a/tests/testthat/_snaps/add_phylopic/phylopic-in-background.svg b/tests/testthat/_snaps/add_phylopic/phylopic-in-background.svg index ca25f80..53e6d1e 100644 --- a/tests/testthat/_snaps/add_phylopic/phylopic-in-background.svg +++ b/tests/testthat/_snaps/add_phylopic/phylopic-in-background.svg @@ -35,21 +35,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/add_phylopic/phylopics-on-top-of-plot.svg b/tests/testthat/_snaps/add_phylopic/phylopics-on-top-of-plot.svg index b254264..eb217a2 100644 --- a/tests/testthat/_snaps/add_phylopic/phylopics-on-top-of-plot.svg +++ b/tests/testthat/_snaps/add_phylopic/phylopics-on-top-of-plot.svg @@ -35,7 +35,7 @@ - + @@ -46,7 +46,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -68,7 +68,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -101,7 +101,7 @@ - + @@ -112,7 +112,7 @@ - + @@ -134,7 +134,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -167,7 +167,7 @@ - + @@ -189,7 +189,7 @@ - + @@ -200,7 +200,7 @@ - + @@ -211,7 +211,7 @@ - + @@ -222,7 +222,7 @@ - + @@ -233,7 +233,7 @@ - + @@ -244,7 +244,7 @@ - + @@ -255,7 +255,7 @@ - + @@ -277,7 +277,7 @@ - + @@ -321,7 +321,7 @@ - + @@ -354,7 +354,7 @@ - + @@ -365,7 +365,7 @@ - + @@ -398,7 +398,7 @@ - + @@ -409,7 +409,7 @@ - + @@ -420,7 +420,7 @@ - + @@ -431,7 +431,7 @@ - + @@ -442,7 +442,7 @@ - + @@ -453,7 +453,7 @@ - + @@ -464,7 +464,7 @@ - + @@ -475,7 +475,7 @@ - + @@ -497,7 +497,7 @@ - + @@ -508,7 +508,7 @@ - + @@ -519,7 +519,7 @@ - + @@ -530,7 +530,7 @@ - + @@ -541,7 +541,7 @@ - + @@ -552,7 +552,7 @@ - + @@ -563,7 +563,7 @@ - + @@ -574,7 +574,7 @@ - + diff --git a/tests/testthat/_snaps/add_phylopic_base/phylopic-in-background.svg b/tests/testthat/_snaps/add_phylopic_base/phylopic-in-background.svg index f6b9bbf..1249d99 100644 --- a/tests/testthat/_snaps/add_phylopic_base/phylopic-in-background.svg +++ b/tests/testthat/_snaps/add_phylopic_base/phylopic-in-background.svg @@ -52,8 +52,8 @@ - - + + diff --git a/tests/testthat/_snaps/add_phylopic_base/phylopics-on-top-of-plot.svg b/tests/testthat/_snaps/add_phylopic_base/phylopics-on-top-of-plot.svg index 91e0d57..4e53e39 100644 --- a/tests/testthat/_snaps/add_phylopic_base/phylopics-on-top-of-plot.svg +++ b/tests/testthat/_snaps/add_phylopic_base/phylopics-on-top-of-plot.svg @@ -54,7 +54,7 @@ - + @@ -65,7 +65,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -87,7 +87,7 @@ - + @@ -98,7 +98,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -120,7 +120,7 @@ - + @@ -131,7 +131,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -153,7 +153,7 @@ - + @@ -175,7 +175,7 @@ - + @@ -186,7 +186,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -208,7 +208,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -230,7 +230,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -252,7 +252,7 @@ - + @@ -263,7 +263,7 @@ - + @@ -274,7 +274,7 @@ - + @@ -285,7 +285,7 @@ - + @@ -296,7 +296,7 @@ - + @@ -307,7 +307,7 @@ - + @@ -318,7 +318,7 @@ - + @@ -329,7 +329,7 @@ - + @@ -340,7 +340,7 @@ - + @@ -351,7 +351,7 @@ - + @@ -362,7 +362,7 @@ - + @@ -373,7 +373,7 @@ - + @@ -384,7 +384,7 @@ - + @@ -395,7 +395,7 @@ - + @@ -417,7 +417,7 @@ - + @@ -428,7 +428,7 @@ - + @@ -439,7 +439,7 @@ - + @@ -450,7 +450,7 @@ - + @@ -461,7 +461,7 @@ - + @@ -472,7 +472,7 @@ - + @@ -483,7 +483,7 @@ - + @@ -494,7 +494,7 @@ - + @@ -505,7 +505,7 @@ - + @@ -516,7 +516,7 @@ - + @@ -527,7 +527,7 @@ - + @@ -538,7 +538,7 @@ - + @@ -549,7 +549,7 @@ - + @@ -560,7 +560,7 @@ - + @@ -571,7 +571,7 @@ - + @@ -582,7 +582,7 @@ - + @@ -593,7 +593,7 @@ - + diff --git a/tests/testthat/_snaps/geom_phylopic/geom-phylopic.svg b/tests/testthat/_snaps/geom_phylopic/geom-phylopic.svg index 2ca6098..f7a30b8 100644 --- a/tests/testthat/_snaps/geom_phylopic/geom-phylopic.svg +++ b/tests/testthat/_snaps/geom_phylopic/geom-phylopic.svg @@ -35,21 +35,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -70,7 +70,7 @@ - + @@ -91,8 +91,8 @@ - - + + @@ -113,8 +113,8 @@ - - + + diff --git a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-img.svg b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-img.svg index 9f9ff18..b6eda00 100644 --- a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-img.svg +++ b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-img.svg @@ -35,8 +35,8 @@ - - + + @@ -47,7 +47,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -89,7 +89,7 @@ - + Felis silvestris catus diff --git a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-larger-glyphs.svg b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-larger-glyphs.svg index 425114e..4d18fba 100644 --- a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-larger-glyphs.svg +++ b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-larger-glyphs.svg @@ -35,8 +35,8 @@ - - + + @@ -47,7 +47,7 @@ - + @@ -78,8 +78,8 @@ - - + + @@ -90,7 +90,7 @@ - + Felis silvestris catus diff --git a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-uuid.svg b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-uuid.svg index 67cc415..d00bd48 100644 --- a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-uuid.svg +++ b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph-with-uuid.svg @@ -35,8 +35,8 @@ - - + + @@ -47,7 +47,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -89,7 +89,7 @@ - + Felis silvestris catus diff --git a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph.svg b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph.svg index 8c97b00..3a341f9 100644 --- a/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph.svg +++ b/tests/testthat/_snaps/geom_phylopic/phylopic-key-glyph.svg @@ -35,8 +35,8 @@ - - + + @@ -47,7 +47,7 @@ - + @@ -78,8 +78,8 @@ - - + + @@ -90,7 +90,7 @@ - + Felis silvestris catus diff --git a/tests/testthat/test-add_phylopic.R b/tests/testthat/test-add_phylopic.R index 447567d..79da2c6 100644 --- a/tests/testthat/test-add_phylopic.R +++ b/tests/testthat/test-add_phylopic.R @@ -27,15 +27,16 @@ test_that("add_phylopic works", { angle <- runif(50, 0, 360) hor <- sample(c(TRUE, FALSE), 50, TRUE) ver <- sample(c(TRUE, FALSE), 50, TRUE) - cols <- sample(c("black", "darkorange", "grey42", "white"), 50, + fills <- sample(c("black", "darkorange", "grey42", "white"), 50, replace = TRUE) + cols <- ifelse(fills == "white", "black", NA) alpha <- runif(50, 0, 1) p <- ggplot(data.frame(cat.x = posx, cat.y = posy), aes(cat.x, cat.y)) + geom_blank() + add_phylopic(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", x = posx, y = posy, ysize = sizey, - fill = cols, alpha = alpha, + fill = fills, color = cols, alpha = alpha, angle = angle, horizontal = hor, vertical = ver) p <- p + ggtitle("R Cat Herd!!") expect_doppelganger("phylopics on top of plot", p) diff --git a/tests/testthat/test-add_phylopic_base.R b/tests/testthat/test-add_phylopic_base.R index 843063b..a5d47a0 100644 --- a/tests/testthat/test-add_phylopic_base.R +++ b/tests/testthat/test-add_phylopic_base.R @@ -25,15 +25,16 @@ test_that("add_phylopic_base works", { angle <- runif(50, 0, 360) hor <- sample(c(TRUE, FALSE), 50, TRUE) ver <- sample(c(TRUE, FALSE), 50, TRUE) - cols <- sample(c("black", "darkorange", "grey42", "white"), 50, - replace = TRUE) + fills <- sample(c("black", "darkorange", "grey42", "white"), 50, + replace = TRUE) + cols <- ifelse(fills == "white", "black", NA) alpha <- runif(50, 0, 1) expect_doppelganger("phylopics on top of plot", function() { plot(posx, posy, type = "n", main = "A cat herd") add_phylopic_base(uuid = "23cd6aa4-9587-4a2e-8e26-de42885004c9", x = posx, y = posy, ysize = sizey, - color = cols, alpha = alpha, + fill = fills, color = cols, alpha = alpha, angle = angle, horizontal = hor, vertical = ver) }) diff --git a/vignettes/a-getting-started.Rmd b/vignettes/a-getting-started.Rmd index 856f18e..214b272 100644 --- a/vignettes/a-getting-started.Rmd +++ b/vignettes/a-getting-started.Rmd @@ -9,7 +9,7 @@ vignette: > **Authors:** Lewis A. Jones & William Gearty -**Last updated:** 2023-11-09 +**Last updated:** 2023-11-16 @@ -171,13 +171,12 @@ The `rotate_phylopic()` function can be used to rotate a silhouette an arbitrary img_rot <- rotate_phylopic(img = img, angle = 45) ``` -Finally, the `recolor_phylopic()` function can be used to modify the color and/or transparency of a silhouette. The vast majority of PhyloPic silhouettes are black and fully opaque by default. However, it may be useful to change this when the you are trying to either match an existing visualization color palette or trying to convey extra information, such as categorical data, through color. +Finally, the `recolor_phylopic()` function can be used to modify the fill color, outline color, and/or transparency of a silhouette. The vast majority of PhyloPic silhouettes are solid black, are fully opaque, and have a transparent outline by default. However, it may be useful to change this when the you are trying to either match an existing visualization color palette or trying to convey extra information, such as categorical data, through color. ```r -# Change color to blue and transparency to 50% -img_col <- recolor_phylopic(img = img, alpha = 0.5, - color = "blue", fill = "blue") +# Change fill color to blue and transparency to 50% +img_col <- recolor_phylopic(img = img, alpha = 0.5, fill = "blue") ``` Let's see what those look like in the same plot: @@ -189,7 +188,7 @@ ggplot() + add_phylopic(img = img_flip, x = 1.25, y = 1.25, ysize = 0.25) + add_phylopic(img = img_rot, x = 1, y = 1, ysize = 0.25) + add_phylopic(img = img_col, x = 0.75, y = 0.75, ysize = 0.25, - color = "original") + fill = "original") ```
@@ -199,7 +198,7 @@ ggplot() + You'll notice that the rotated silhouette is smaller than the other two silhouettes. This is because our functions have arguments to specify the height (`ysize`). The width is automatically set to maintain the original aspect ratio of the silhouette. In this case, the aspect ratio of the rotated silhouette has changed, so the same height results in a smaller silhouette overall. -For convenience, we have also included these transformation options within all of the visualization functions. The default color is "black", hence why we needed to specify `color = "original"` above. However, when the same transformed silhouette will be used for multiple visualizations, we suggest transforming the silhouette first, saving it as a new object, then using this new object for visualization purposes. +For convenience, we have also included these transformation options within all of the visualization functions. The default fill is "black", hence why we needed to specify `fill = "original"` above. However, when the same transformed silhouette will be used for multiple visualizations, we suggest transforming the silhouette first, saving it as a new object, then using this new object for visualization purposes. ## Get attribution Now that you've made a plot and used some silhouettes, you should acknowledge the contributors that made those silhouettes. Fortunately, **rphylopic** includes the `get_attribution()` function to get contributor data about specific images: diff --git a/vignettes/a-getting-started.Rmd.orig b/vignettes/a-getting-started.Rmd.orig index 20f54ae..f715f3c 100644 --- a/vignettes/a-getting-started.Rmd.orig +++ b/vignettes/a-getting-started.Rmd.orig @@ -135,12 +135,11 @@ The `rotate_phylopic()` function can be used to rotate a silhouette an arbitrary img_rot <- rotate_phylopic(img = img, angle = 45) ``` -Finally, the `recolor_phylopic()` function can be used to modify the color and/or transparency of a silhouette. The vast majority of PhyloPic silhouettes are black and fully opaque by default. However, it may be useful to change this when the you are trying to either match an existing visualization color palette or trying to convey extra information, such as categorical data, through color. +Finally, the `recolor_phylopic()` function can be used to modify the fill color, outline color, and/or transparency of a silhouette. The vast majority of PhyloPic silhouettes are solid black, are fully opaque, and have a transparent outline by default. However, it may be useful to change this when the you are trying to either match an existing visualization color palette or trying to convey extra information, such as categorical data, through color. ```{r} -# Change color to blue and transparency to 50% -img_col <- recolor_phylopic(img = img, alpha = 0.5, - color = "blue", fill = "blue") +# Change fill color to blue and transparency to 50% +img_col <- recolor_phylopic(img = img, alpha = 0.5, fill = "blue") ``` Let's see what those look like in the same plot: @@ -151,12 +150,12 @@ ggplot() + add_phylopic(img = img_flip, x = 1.25, y = 1.25, ysize = 0.25) + add_phylopic(img = img_rot, x = 1, y = 1, ysize = 0.25) + add_phylopic(img = img_col, x = 0.75, y = 0.75, ysize = 0.25, - color = "original") + fill = "original") ``` You'll notice that the rotated silhouette is smaller than the other two silhouettes. This is because our functions have arguments to specify the height (`ysize`). The width is automatically set to maintain the original aspect ratio of the silhouette. In this case, the aspect ratio of the rotated silhouette has changed, so the same height results in a smaller silhouette overall. -For convenience, we have also included these transformation options within all of the visualization functions. The default color is "black", hence why we needed to specify `color = "original"` above. However, when the same transformed silhouette will be used for multiple visualizations, we suggest transforming the silhouette first, saving it as a new object, then using this new object for visualization purposes. +For convenience, we have also included these transformation options within all of the visualization functions. The default fill is "black", hence why we needed to specify `fill = "original"` above. However, when the same transformed silhouette will be used for multiple visualizations, we suggest transforming the silhouette first, saving it as a new object, then using this new object for visualization purposes. ## Get attribution Now that you've made a plot and used some silhouettes, you should acknowledge the contributors that made those silhouettes. Fortunately, **rphylopic** includes the `get_attribution()` function to get contributor data about specific images: diff --git a/vignettes/b-advanced-ggplot.Rmd b/vignettes/b-advanced-ggplot.Rmd index ff4bc3f..e04cb2c 100644 --- a/vignettes/b-advanced-ggplot.Rmd +++ b/vignettes/b-advanced-ggplot.Rmd @@ -9,7 +9,7 @@ vignette: > **Authors:** William Gearty & Lewis A. Jones -**Last updated:** 2023-11-09 +**Last updated:** 2023-11-16 @@ -124,19 +124,20 @@ ggplot(penguins_subset) +

plot of chunk ggplot-penguin-plot-4

-Finally, let's color the female and male penguins with different colors. Note that the default for `geom_phylopic()` is to not display a legend, so we need to set `show.legend = TRUE`. However, we only want a legend for the colors, so we use `guide = "none"` for the size scale: +Finally, let's give the female and male penguins different fill colors. Note that the default for `geom_phylopic()` is to not display a legend, so we need to set `show.legend = TRUE`. However, we only want a legend for the fill colors, so we use `guide = "none"` for the size scale. We also want to show the fill color in the legend, so we need to override the shape: ```r ggplot(penguins_subset) + geom_phylopic(img = penguin_rot, aes(x = bill_length_mm, y = flipper_length_mm, - size = body_mass_g, color = sex), + size = body_mass_g, fill = sex), show.legend = TRUE) + labs(x = "Bill length (mm)", y = "Flipper length (mm)") + scale_size_continuous(guide = "none") + - scale_color_manual("Sex", values = c("orange", "blue"), - labels = c("Female", "Male")) + + scale_fill_manual("Sex", values = c("orange", "blue"), + labels = c("Female", "Male"), + guide = guide_legend(override.aes = list(shape = 21))) + facet_wrap(~species, ncol = 1) + theme_bw(base_size = 15) + theme(legend.position = c(0.9, 0.9)) @@ -154,12 +155,12 @@ Hmm...the colored dots in the legend are great, but lucky for us, the package al ggplot(penguins_subset) + geom_phylopic(img = penguin_rot, aes(x = bill_length_mm, y = flipper_length_mm, - size = body_mass_g, color = sex), + size = body_mass_g, fill = sex), show.legend = TRUE, key_glyph = phylopic_key_glyph(img = penguin_rot)) + labs(x = "Bill length (mm)", y = "Flipper length (mm)") + scale_size_continuous(guide = "none") + - scale_color_manual("Sex", values = c("orange", "blue"), + scale_fill_manual("Sex", values = c("orange", "blue"), labels = c("Female", "Male")) + facet_wrap(~species, ncol = 1) + theme_bw(base_size = 15) + @@ -198,7 +199,7 @@ Then we'll subset our occurrences to only those for *Diplocaulus*: tetrapods <- subset(tetrapods, genus == "Diplocaulus") ``` -Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the color, the more occurrences in that geographic location. +Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the fill color, the more occurrences in that geographic location. ```r @@ -209,7 +210,7 @@ world <- st_wrap_dateline(world) ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_point(data = tetrapods, aes(x = lng, y = lat), - size = 4, alpha = 0.75, color = "blue") + + size = 4, alpha = 0.75, fill = "blue") + theme_void() + coord_sf() ``` @@ -226,7 +227,7 @@ Now, as with the penguin figure above, we can easily replace those points with s ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus), - size = 4, alpha = 0.75, color = "blue") + + size = 4, alpha = 0.75, fill = "blue") + theme_void() + coord_sf() ``` @@ -250,7 +251,7 @@ bbox <- st_graticule(crs = st_crs("ESRI:54030"), ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus), - size = 4E5, alpha = 0.75, color = "blue") + + size = 4E5, alpha = 0.75, fill = "blue") + geom_sf(data = bbox) + theme_void() + coord_sf(default_crs = st_crs(4326), crs = st_crs("ESRI:54030")) diff --git a/vignettes/b-advanced-ggplot.Rmd.orig b/vignettes/b-advanced-ggplot.Rmd.orig index aee3b95..ef31a81 100644 --- a/vignettes/b-advanced-ggplot.Rmd.orig +++ b/vignettes/b-advanced-ggplot.Rmd.orig @@ -103,18 +103,19 @@ ggplot(penguins_subset) + theme_bw(base_size = 15) ``` -Finally, let's color the female and male penguins with different colors. Note that the default for `geom_phylopic()` is to not display a legend, so we need to set `show.legend = TRUE`. However, we only want a legend for the colors, so we use `guide = "none"` for the size scale: +Finally, let's give the female and male penguins different fill colors. Note that the default for `geom_phylopic()` is to not display a legend, so we need to set `show.legend = TRUE`. However, we only want a legend for the fill colors, so we use `guide = "none"` for the size scale. We also want to show the fill color in the legend, so we need to override the shape: ```{r ggplot-penguin-plot-5} ggplot(penguins_subset) + geom_phylopic(img = penguin_rot, aes(x = bill_length_mm, y = flipper_length_mm, - size = body_mass_g, color = sex), + size = body_mass_g, fill = sex), show.legend = TRUE) + labs(x = "Bill length (mm)", y = "Flipper length (mm)") + scale_size_continuous(guide = "none") + - scale_color_manual("Sex", values = c("orange", "blue"), - labels = c("Female", "Male")) + + scale_fill_manual("Sex", values = c("orange", "blue"), + labels = c("Female", "Male"), + guide = guide_legend(override.aes = list(shape = 21))) + facet_wrap(~species, ncol = 1) + theme_bw(base_size = 15) + theme(legend.position = c(0.9, 0.9)) @@ -126,12 +127,12 @@ Hmm...the colored dots in the legend are great, but lucky for us, the package al ggplot(penguins_subset) + geom_phylopic(img = penguin_rot, aes(x = bill_length_mm, y = flipper_length_mm, - size = body_mass_g, color = sex), + size = body_mass_g, fill = sex), show.legend = TRUE, key_glyph = phylopic_key_glyph(img = penguin_rot)) + labs(x = "Bill length (mm)", y = "Flipper length (mm)") + scale_size_continuous(guide = "none") + - scale_color_manual("Sex", values = c("orange", "blue"), + scale_fill_manual("Sex", values = c("orange", "blue"), labels = c("Female", "Male")) + facet_wrap(~species, ncol = 1) + theme_bw(base_size = 15) + @@ -163,7 +164,7 @@ Then we'll subset our occurrences to only those for *Diplocaulus*: tetrapods <- subset(tetrapods, genus == "Diplocaulus") ``` -Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the color, the more occurrences in that geographic location. +Now, let's plot those occurrences on a world map. `{ggplot2}` and it's built-in function `map_data()` make this a breeze. Note that we use `alpha = 0.75` in case there are multiple occurrences in the same place. That way, the darker the fill color, the more occurrences in that geographic location. ```{r ggplot-geog-plot-1, fig.height = 3.5} # Get map data @@ -173,7 +174,7 @@ world <- st_wrap_dateline(world) ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_point(data = tetrapods, aes(x = lng, y = lat), - size = 4, alpha = 0.75, color = "blue") + + size = 4, alpha = 0.75, fill = "blue") + theme_void() + coord_sf() ``` @@ -184,7 +185,7 @@ Now, as with the penguin figure above, we can easily replace those points with s ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus), - size = 4, alpha = 0.75, color = "blue") + + size = 4, alpha = 0.75, fill = "blue") + theme_void() + coord_sf() ``` @@ -202,7 +203,7 @@ bbox <- st_graticule(crs = st_crs("ESRI:54030"), ggplot(world) + geom_sf(fill = "lightgray", color = "darkgrey", linewidth = 0.1) + geom_phylopic(data = tetrapods, aes(x = lng, y = lat, name = genus), - size = 4E5, alpha = 0.75, color = "blue") + + size = 4E5, alpha = 0.75, fill = "blue") + geom_sf(data = bbox) + theme_void() + coord_sf(default_crs = st_crs(4326), crs = st_crs("ESRI:54030")) diff --git a/vignettes/base-geog-plot-1-1.png b/vignettes/base-geog-plot-1-1.png index e4d5cab938df98ede06f8d532fec4951659a83f0..f3bc3e2c11f7ca7530bdd6fcf73994b8681c6272 100644 GIT binary patch literal 29302 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