Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scales 1.4.0 #711

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
184 changes: 184 additions & 0 deletions content/blog/scales-1-4-0/index.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
output: hugodown::hugo_document

slug: scales-1-4-0
title: scales 1.4.0
date: 2024-10-30
author: Teun van den Brand
description: >
The new 1.4.0 release of the scales package adds some colourful updates.
Read about colour manipulation, palettes and new label functions.

photo:
url: https://unsplash.com/photos/a-close-up-of-a-person-holding-a-paintbrush-Xrelr7cTYm4
author: Jennie Razumnaya

# one of: "deep-dive", "learn", "package", "programming", "roundup", or "other"
categories: [package]
tags: [scales]
---

<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with `hugodown::tidy_show_meta()`)
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] `hugodown::use_tidy_thumbnails()`
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] `usethis::use_tidy_thanks()`
-->

We're stoked to announce the release of [scales]({https://scales.r-lib.org/}) 1.4.0.
scales is a package that provides much of the scaling logic that is used in ggplot2 to a general framework, along with utility functions for e.g. formatting labels or creating colour palettes.

You can install it from CRAN with:

```{r, eval = FALSE}
install.packages("scales")
```

This blog post will give an overview of the 1.4.0 release, which has some nifty upgrades for working with colours and labels.

You can see a full list of changes in the [release notes](https://scales.r-lib.org/news/index.html)

```{r setup}
library(scales)
```

```{r ragg, include=FALSE}
knitr::opts_chunk$set(dev = "ragg_png")
```

## Colour manipulation

The `alpha()` and `muted()` functions have been part of scales for a long time.
Back in the 1.1.0 release we swapped to [farver](https://farver.data-imaginist.com/) to power these functions.
We felt it was appropriate to use this package for other common colour tasks, and so `col_shift()`, `col_lighter()`, `col_darker()`, `col_saturate()` and `col_mix()` were born.

```{r}
my_colours <- c("red", "green", "blue")

m <- rbind(
original = my_colours,
shift = col_shift(my_colours, 90),
lighter = col_lighter(my_colours, 20),
darker = col_darker(my_colours, 20),
duller = col_saturate(my_colours, -50),
mixed = col_mix(my_colours, "orchid")
)

show_col(t(m), ncol = ncol(m))
text(x = ncol(m) + 0.25, y = -(1:nrow(m)) + 0.5, rownames(m), adj = 0)
```

## Palettes

Palettes have also been reworked in this release to include some useful properties.
Palettes now come in one of two classes: 'pal_discrete' or 'pal_continuous'.

```{r}
my_palette <- manual_pal(c("palegreen", "deepskyblue", "magenta"))
class(my_palette)
```

Having palettes as a class rather than as plain functions, allows us to store useful metadata about the palette which can be used downstream.
In addition, most colour palette functions also allow the aforementioned colour manipulation functions to work on the palette output.

```{r}
palette_type(my_palette)

palette_nlevels(my_palette)

col_shift(my_palette, 180)(3)
```

With the new setup it is now possible to expand discrete palettes to continuous palettes with `as_continuous_pal()` or vise versa to chop up continuous palettes into discrete palettes with `as_discrete_pal()`.

```{r}
plot(as_continuous_pal(my_palette))
```

Another quality of life improvement for palettes, is that the 'scales' package now keeps track of named palettes.
By default, the collection of 'known' palettes is pre-populated with colour palettes from the grDevices, RColorBrewer and viridisLite packages.


```{r}
head(palette_names())

get_palette("Okabe-Ito")(8)
```

If you're a developer of a palette package, you can use `set_palette()` to register your palette.
This has the advantage that your palette is now available to users by name, which at times might be more convenient than having to call the palette generator function.
In the future, we plan to make it easier to work with named palettes in ggplot2.
Hopefully this will mean that mirroring every palette in a `scale_*()` function becomes obsolete.

```{r, error=TRUE}
get_palette("aurora")

set_palette("aurora", my_palette)
plot(get_palette("aurora"))
```

## Labels

This release also provides improvements to labelling in the form of two new labelling functions and two new convenience functions for labels.
In contrast to most of scales' label functions, these label functions are great for discrete input.
First up is `label_glue()`, which uses the string interpolation from the glue package to format your labels.

```{r}
label_glue("The {x} penguin")(c("Gentoo", "Chinstrap", "Adelie"))
```

The other labelling function, `label_dictionary()`, is convenient when some variable you use consists of short-codes or abbreviations.
You can provide `label_dictionary()` with a named vector that translates the values to prettier labels.
If one or more of your values doesn't exist in the dictionary, they stay as-is by default.

```{r}
dict <- c(
diy = "Do it yourself", eta = "Estimated time of arrival",
asap = "As soon as possible", tldr = "Too long; didn't read"
)
label_dictionary(dict)(c("diy", "tldr", "bff"))
```

`compose_label()` is a useful convenience function we've added which will help you to create custom labelling behaviour without needing to write a labelling function from scratch.
Similar to `compose_trans()`, it allows you to chain together different labelling functions.

```{r}
screaming_flowers <- compose_label(label_glue("The {x} flower"), toupper)
screaming_flowers(c("daffodil", "orchid", "tulip"))
```
Lastly, we haven't completely forgotton about numeric labels either.
We have introduced the `number_options()` functions to globally populate defaults for functions such as `label_number()` and `label_currency()`.
This can be convenient if you produce statistical reports in non-English languages.

```{r}
number_options(
decimal.mark = ",",
big.mark = ".",
style_negative = "minus",
currency.prefix = "",
currency.suffix = "€",
currency.decimal.mark = ",",
currency.big.mark = " ",
ordinal.rules = ordinal_french()
)

label_currency(accuracy = 0.01)(c(0.1, 10, 1000000, -1000))

label_ordinal()(1:4)
```



## Acknowledgements

We'd like to thank all people who have contributed in some way, whether it was filing issues, participating in discussion or contributing to code and documentation:

[&#x0040;Aariq](https://github.com/Aariq), [&#x0040;Aehmlo](https://github.com/Aehmlo), [&#x0040;Ali-Hudson](https://github.com/Ali-Hudson), [&#x0040;cb12991](https://github.com/cb12991), [&#x0040;colindouglas](https://github.com/colindouglas), [&#x0040;d-morrison](https://github.com/d-morrison), [&#x0040;davidhodge931](https://github.com/davidhodge931), [&#x0040;EricMarcon](https://github.com/EricMarcon), [&#x0040;kellijohnson-NOAA](https://github.com/kellijohnson-NOAA), [&#x0040;kmcd39](https://github.com/kmcd39), [&#x0040;lz1nwm](https://github.com/lz1nwm), [&#x0040;mine-cetinkaya-rundel](https://github.com/mine-cetinkaya-rundel), [&#x0040;mjskay](https://github.com/mjskay), [&#x0040;Moohan](https://github.com/Moohan), [&#x0040;muschellij2](https://github.com/muschellij2), [&#x0040;ppreshant](https://github.com/ppreshant), [&#x0040;rawktheuniversemon](https://github.com/rawktheuniversemon), [&#x0040;rogiersbart](https://github.com/rogiersbart), [&#x0040;SchmidtPaul](https://github.com/SchmidtPaul), [&#x0040;teunbrand](https://github.com/teunbrand), and [&#x0040;thomasp85](https://github.com/thomasp85).


Loading