From dff1287e9a6d1aa570233636176a264fda1dad93 Mon Sep 17 00:00:00 2001 From: gnoblet Date: Sun, 22 Jan 2023 08:09:49 -0500 Subject: [PATCH] Donut 1st version --- R/donut.R | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 R/donut.R diff --git a/R/donut.R b/R/donut.R new file mode 100644 index 0000000..3a75efb --- /dev/null +++ b/R/donut.R @@ -0,0 +1,109 @@ +#' @title Simple donut chart (to be used parsimoniously), can be a pie chart +#' +#' @param df A data frame. +#' @param x A character column or coercible as a character column. Will give the donut's fill color. +#' @param y A numeric column. +#' @param alpha Fill transparency. +#' @param x_title The x scale title. Default to NULL. +#' @param title Plot title. Default to NULL. +#' @param subtitle Plot subtitle. Default to NULL. +#' @param caption Plot caption. Default to NULL. +#' @param arrange TRUE or FALSE. Arrange by highest percentage first. +#' @param hole_size Hole size. Default to 3. If less than 2, back to a pie chart. +#' @param add_text TRUE or FALSE. Add the value as text. +#' @param add_text_treshold_display Minimum value to add the text label. +#' @param add_text_color Text color. +#' @param add_text_suffix If percent is FALSE, should we add a suffix to the text label? +#' @param theme Whatever theme. Default to theme_reach(). +#' +#' @return A donut chart to be used parsimoniously +#' +#' @export +donut <- function(df, + x, + y, + alpha = 1, + x_title = NULL, + title = NULL, + subtitle = NULL, + caption = NULL, + arrange = TRUE, + hole_size = 3, + add_text = TRUE, + add_text_treshold_display = 5, add_text_color = "white", add_text_suffix = "", theme = theme_reach(legend_reverse = TRUE)){ + + # Arrange by biggest prop first ? + if (arrange) df <- dplyr::arrange( + df, + {{ y }} + ) + + # Get levels for scaling + lev <- dplyr::pull(df, {{ x }}) + df <- dplyr::mutate(df, "{{x}}" := factor({{ x }}, levels = lev)) + + # Mapping + g <- ggplot2::ggplot( + df, + mapping = ggplot2::aes( + x = hole_size, + y = {{ y }}, + fill = {{ x }}, + color = {{ x }} + ) + ) + + # Add rect + g <- g + ggplot2::geom_col(alpha = alpha) + + + # Add text labels + if (add_text) { + + df <- dplyr::mutate(df, y_treshold = ifelse({{ y }} >= add_text_treshold_display, {{ y }}, NA )) + + g <- g + + ggplot2::geom_text( + data = df, + ggplot2::aes( + x = hole_size, + y = !!rlang::sym("y_treshold"), + label = paste0({{ y }}, add_text_suffix)), + color = add_text_color, + position = ggplot2::position_stack(vjust = 0.5)) + } + + # Add title, subtitle, caption, x_title, y_title + g <- g + ggplot2::labs( + title = title, + subtitle = subtitle, + caption = caption, + fill = x_title, + color = x_title + ) + + # Transform to polar coordinates and adjust hole + g <- g + + ggplot2::coord_polar( + theta = "y" + ) + if (hole_size >= 2) g <- g + ggplot2::xlim(c(1, hole_size + 0.5)) # Try to remove that to see how to make a pie chart + + # No axis + g <- g + ggplot2::theme( + axis.line.x = ggplot2::element_blank(), + axis.ticks.x = ggplot2::element_blank(), + axis.text.x = ggplot2::element_blank(), + axis.title.x = ggplot2::element_blank(), + axis.line.y = ggplot2::element_blank(), + axis.ticks.y = ggplot2::element_blank(), + axis.text.y = ggplot2::element_blank(), + axis.title.y = ggplot2::element_blank() + ) + + # Add theme + g <- g + theme + + return(g) + +}