Skip to content

Commit

Permalink
Merge pull request #22 from DataScienceScotland/sg-palettes
Browse files Browse the repository at this point in the history
Add SG colour palettes
  • Loading branch information
alice-hannah authored Aug 29, 2023
2 parents 1871b1c + 1916519 commit 9799517
Show file tree
Hide file tree
Showing 44 changed files with 639 additions and 266 deletions.
12 changes: 7 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: sgplot
Title: Graphic Styles and Colours for Scottish Government Plots
Version: 0.1.0
Version: 0.2.0
Authors@R: c(
person("Scottish Government", , , "statistics.enquiries@gov.scot", role = c("cph", "fnd")),
person("Alice", "Byers", , "alice.byers@gov.scot", c("aut", "cre"))
Expand All @@ -17,9 +17,10 @@ RoxygenNote: 7.2.3
Depends:
R (>= 2.10)
Imports:
ggplot2,
scales,
cli
ggplot2,
scales,
cli,
rlang
Suggests:
dplyr,
knitr,
Expand All @@ -31,5 +32,6 @@ Suggests:
gapminder,
stringr,
testthat (>= 2.1.0),
plotly
plotly,
gt
VignetteBuilder: knitr
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export(scale_fill_continuous_sg)
export(scale_fill_discrete_sg)
export(theme_sg)
export(use_sgplot)
importFrom(rlang,.data)
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# sgplot 0.2.0

* Add [Scottish Government Design System colour palettes](https://designsystem.gov.scot/guidance/charts/data-visualisation-colour-palettes)
* Reduce `base_line_size` in `theme_sg()`
* Remove default dark blue outline from `geom_col` and `geom_bar` when using `use_sgplot()`.

# sgplot 0.1.0

* First package release
Expand Down
41 changes: 41 additions & 0 deletions R/colour_table.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#' @title Create \code{gt} table of colour palette
#'
#' @param pal Named vector of colour palette;
#' e.g. \code{sgplot::sg_colour_palettes[["main"]]}
#'
#' @return An object of class \code{gt_tbl}.

colour_table <- function(pal) {

tibble::enframe(pal) |>
dplyr::mutate(example = "") |>
dplyr::mutate(value = factor(
pal,
ordered = TRUE,
levels = unname(pal)
)) |>
gt::gt() |>
gt::data_color(
columns = .data$value,
target_columns = .data$example,
fn = scales::col_factor(
palette = pal,
domain = NULL
)
) |>
gt::cols_width(
name ~ gt::px(110),
value ~ gt::px(100),
example ~ gt::px(150)
) |>
gt::cols_align(
align = "left",
columns = dplyr::everything()
) |>
gt::cols_label(
name = "Colour name",
value = "Hex code",
example = "Example of colour"
)

}
29 changes: 27 additions & 2 deletions R/data.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#' hex code.
#'
#' @format A character vector
#' @source \href{https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/}{Government Analysis Function Colours Guidance}
#' @source \href{https://designsystem.gov.scot/guidance/charts/data-visualisation-colour-palettes}{Scottish Government Design System}
# nolint end

"sg_colour_values"
Expand All @@ -17,7 +17,32 @@
#' @description A list grouping colours into palettes.
#'
#' @format A character list
#' @source \href{https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/}{Government Analysis Function Colours Guidance}
#' @source \href{https://designsystem.gov.scot/guidance/charts/data-visualisation-colour-palettes}{Scottish Government Design System}
# nolint end

"sg_colour_palettes"


# nolint start
#' @title Analysis Function colour names and hex codes
#'
#' @description A vector containing colour names and their corresponding
#' hex code.
#'
#' @format A character vector
#' @source \href{https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/}{Government Analysis Function Colours Guidance}
# nolint end

"af_colour_values"


# nolint start
#' @title Analysis Function colour palettes
#'
#' @description A list grouping colours into palettes.
#'
#' @format A character list
#' @source \href{https://analysisfunction.civilservice.gov.uk/policy-store/data-visualisation-colours-in-charts/}{Government Analysis Function Colours Guidance}
# nolint end

"af_colour_palettes"
22 changes: 16 additions & 6 deletions R/scale_colour_continuous_sg.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#' @title Continuous colour scales for Scottish Government plots
#'
#' @param palette Name of palette to use from `sg_colour_palettes`; e.g. main,
#' sequential, focus. Default value is 'sequential'.
#' @param palette Name of palette to use; e.g. "main", "sequential", "focus".
#' Default value is "sequential".
#' @param palette_type Either "sg" to use Scottish Government palettes, or "af"
#' to use Analysis Function palettes. Defaults to "sg".
#' @param reverse Boolean value to indicate whether the palette should be
#' reversed.
#' @param na_colour Colour to set for missing values.
Expand All @@ -18,22 +20,30 @@
#' @export

scale_colour_continuous_sg <- function(palette = "sequential",
palette_type = c("sg", "af"),
reverse = FALSE,
na_colour = "grey50",
guide = "colourbar",
...) {

palette_type <- match.arg(palette_type)

palette_list <- get(paste0(palette_type, "_colour_palettes"),
as.environment("package:sgplot"))

# Error if palette doesn't exist
if (!palette %in% names(sgplot::sg_colour_palettes)) {
if (!palette %in% names(palette_list)) {
cli::cli_abort(c(
"x" = paste(palette, "is not a valid palette name.")
"x" = paste("`{palette}` is not a valid palette name in",
"`{palette_type}_colour_palettes`.")
))
}

colours <- as.vector(sgplot::sg_colour_palettes[[palette]])
colours <- as.vector(palette_list[[palette]])

ggplot2::continuous_scale(
aesthetics = "colour",
scale_name = "sg_continuous",
scale_name = paste0(palette_type, "_continuous"),
palette = scales::gradient_n_pal(colours, values = NULL, "Lab"),
na.value = na_colour,
guide = guide,
Expand Down
16 changes: 11 additions & 5 deletions R/scale_colour_discrete_sg.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#' @title Discrete colour scales for Scottish Government plots
#'
#' @param palette Name of palette to use from `sg_colour_palettes`; e.g. main,
#' sequential, focus. Default value is 'main'.
#' @param palette Name of palette to use; e.g. "main", "sequential", "focus."
#' Default value is "main".
#' @param palette_type Either "sg" to use Scottish Government palettes, or "af"
#' to use Analysis Function palettes. Defaults to "sg".
#' @param reverse Boolean value to indicate whether the palette should be
#' reversed.
#' @param ... Additional arguments passed to scale type.
Expand All @@ -14,16 +16,20 @@
#' filter(variable %in% c("psavert", "uempmed")) %>%
#' ggplot(aes(x = date, y = value, colour = variable)) +
#' geom_line(linewidth = 1) +
#' scale_colour_discrete_sg("main2")
#' scale_colour_discrete_sg()
#'
#' @export

scale_colour_discrete_sg <- function(palette = "main",
palette_type = c("sg", "af"),
reverse = FALSE,
...) {

palette_type <- match.arg(palette_type)

ggplot2::discrete_scale("colour",
paste0("sg_", palette),
palette = sg_palette(palette, reverse),
paste0(palette_type, "_", palette),
palette = sg_palette(palette, reverse, palette_type = palette_type),
...
)
}
22 changes: 16 additions & 6 deletions R/scale_fill_continuous_sg.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#' @title Continuous colour fill scales for Scottish Government plots
#'
#' @param palette Name of palette to use from `sg_colour_palettes`; e.g. main,
#' sequential, focus. Default value is 'sequential'.
#' @param palette Name of palette to use; e.g. "main", "sequential", "focus."
#' Default value is "sequential".
#' @param palette_type Either "sg" to use Scottish Government palettes, or "af"
#' to use Analysis Function palettes. Defaults to "sg".
#' @param reverse Boolean value to indicate whether the palette should be
#' reversed.
#' @param na_colour Colour to set for missing values.
Expand All @@ -18,22 +20,30 @@
#' @export

scale_fill_continuous_sg <- function(palette = "sequential",
palette_type = c("sg", "af"),
reverse = FALSE,
na_colour = "grey50",
guide = "colourbar",
...) {

palette_type <- match.arg(palette_type)

palette_list <- get(paste0(palette_type, "_colour_palettes"),
as.environment("package:sgplot"))

# Error if palette doesn't exist
if (!palette %in% names(sgplot::sg_colour_palettes)) {
if (!palette %in% names(palette_list)) {
cli::cli_abort(c(
"x" = paste(palette, "is not a valid palette name.")
"x" = paste("`{palette}` is not a valid palette name in",
"`{palette_type}_colour_palettes`.")
))
}

colours <- as.vector(sgplot::sg_colour_palettes[[palette]])
colours <- as.vector(palette_list[[palette]])

ggplot2::continuous_scale(
aesthetics = "fill",
scale_name = "sg_continuous",
scale_name = paste0(palette_type, "_continuous"),
palette = scales::gradient_n_pal(colours, values = NULL, "Lab"),
na.value = na_colour,
guide = guide,
Expand Down
14 changes: 10 additions & 4 deletions R/scale_fill_discrete_sg.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#' @title Discrete colour fill scales for Scottish Government plots
#'
#' @param palette Name of palette to use from `sg_colour_palettes`; e.g. main,
#' sequential, focus. Default value is 'main'.
#' @param palette Name of palette to use; e.g. "main", "sequential", "focus."
#' Default value is "main."
#' @param palette_type Either "sg" to use Scottish Government palettes, or "af"
#' to use Analysis Function palettes. Defaults to "sg".
#' @param reverse Boolean value to indicate whether the palette should be
#' reversed.
#' @param ... Additional arguments passed to scale type.
Expand All @@ -18,11 +20,15 @@
#' @export

scale_fill_discrete_sg <- function(palette = "main",
palette_type = c("sg", "af"),
reverse = FALSE,
...) {

palette_type <- match.arg(palette_type)

ggplot2::discrete_scale("fill",
paste0("sg_", palette),
palette = sg_palette(palette, reverse),
paste0(palette_type, "_", palette),
palette = sg_palette(palette, reverse, palette_type = palette_type),
...
)
}
45 changes: 32 additions & 13 deletions R/sg_palette.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,66 @@
#' reversed
#' @param colour_names Boolean value to indicate whether colour names should be
#' included
#' @param palette_type Either `sg` to use Scottish Government palettes, or `af`
#' to use Analysis Function palettes. Defaults to `sg`.

sg_palette <- function(palette = "main",
reverse = FALSE,
colour_names = FALSE) {
colour_names = FALSE,
palette_type = c("sg", "af")) {

palette_type <- match.arg(palette_type)

palette_list <- get(paste0(palette_type, "_colour_palettes"))

# Check valid palette name
if (!palette %in% names(sgplot::sg_colour_palettes)) {
if (!palette %in% names(palette_list)) {
cli::cli_abort(c(
"x" = paste0("`", palette, "` is not a valid palette name.")
"x" = paste("`{palette}` is not a valid palette name ",
"in `{palette_type}_colour_palettes`.")
))
}

function(n) {
n_available <- length(sgplot::sg_colour_palettes[[palette]])
n_available <- length(palette_list[[palette]])

# Use 'main2' if main palette used and only 2 colours required
if (n == 2 && palette != "main2" && grepl("main", palette)) {
# Use 'main2' if AF main palette used and only 2 colours required
if (
palette_type == "af" &&
n == 2 &&
palette != "main2" &&
grepl("main", palette)
) {
palette <- "main2"
cli::cli_warn(c(
"!" = "Using `main2` as only two colours are required."
))
}

ext_palettes <- subset(
names(palette_list),
stringr::str_detect(names(palette_list), "^main([5-9]|-extended)")
)

# Error if more colours requested than exist in palette
if (n > n_available) {
cli::cli_abort(c(
"x" = paste0(
"There are not enough colours available in the `",
palette, "` palette (", n_available, " available)."
"x" = glue::glue(
"There are not enough colours available in the `{palette}`",
"palette from `{palette_type}_colour_palettes`",
"({n_available} available)."
),
"i" = paste(
"i" = glue::glue(
"Accessibility guidance recommends a limit of four",
"colours per chart. If more than four colours are",
"required, first consider chart redesign. If it is",
"essential to use more than four colours, the `main6`",
"palette can be used."
"essential to use more than four colours, the `{ext_palettes}`",
"palette{?s} can be used."
)
))
}

pal <- sgplot::sg_colour_palettes[[palette]][seq_len(n)]
pal <- palette_list[[palette]][seq_len(n)]

if (reverse) pal <- rev(pal)

Expand Down
7 changes: 7 additions & 0 deletions R/sgplot-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#' @keywords internal
"_PACKAGE"

## usethis namespace: start
#' @importFrom rlang .data
## usethis namespace: end
NULL
4 changes: 2 additions & 2 deletions R/theme_sg.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@


theme_sg <- function(base_size = 12,
base_line_size = base_size / 22,
base_rect_size = base_size / 22,
base_line_size = base_size / 24,
base_rect_size = base_size / 24,
grid = c("y", "x", "xy", "none"),
axis = c("x", "y", "xy", "none"),
ticks = c("xy", "x", "y", "none"),
Expand Down
Loading

0 comments on commit 9799517

Please sign in to comment.