I’m happy to announce my newest package prismatic which facilitates simple manipulations of colors. I had been working on this package online and offline for some time, but the promise of easy manipulation of mapped data in ggplot2 forced me to get some work done to get this package out before ggplot2 version 3.3.0. (as of the time of writing.)
This post will go over some of the finer details with lots of pretty pictures!
Loading Packages
The prismatic package is a fairly low dependency with only 1 import being farver for lightning-fast conversion between color spaces. I have also loaded the colorspace package, from which some of the following functions have been inspired. I will use colorspace to enable the plotting of multiple color palettes side by side, but I will not showcase the code each time. Go to the end of the post for example code for comparison plots.
library(prismatic)
library(colorspace) # for plotting functions
##
## Attaching package: 'colorspace'
## The following object is masked from 'package:prismatic':
##
## contrast_ratio
library(magrittr) # for the glorious pipe
Let me see the colors!!
If you have seen my work, you will properly know that I like colors alot! But being also to quickly inspect some colors have always been a little too much work. Now all you have to do it pass your colors to color()
(or colour()
for our friends across the pond) to get a plot()
method
rainbow(10) %>% color() %>% plot()
hcl.colors(25) %>% color() %>% plot()
::scico(256, palette = "buda") %>% color() %>% plot() scico
Which I would like to think is one of the main features of the package. If you happen to have crayon available you will see an approximation of the colors with a filled-in background (this is limited to 256 colors so your mileage might vary, when in doubt use plot()
)
This is the extent of what the color object can do.
Manipulations
The second star of the package is the collection of functions to manipulate the colors. All these functions have a couple of things in common.
- They all start with
clr_
for easy auto-completion in your favorite IDE. - They all take a vector of colors as the first argument and results in a colors object of the same length.
these two facts make the function super pipe friendly.
Saturation
The two functions clr_saturate()
and clr_desaturate()
both modifies the saturation of a color. It takes a single additional argument to specify the degree to which the (de)saturation should occur. These values should be between 0(nothing happens) and 1(full on power!).
notice how you don’t have to call color()
on the output of clr_desaturate()
as it already returns a colors object.
hcl.colors(10, "plasma") %>%
clr_desaturate(0.8) %>%
plot()
Examples are done with Mango palette from LaCroixColoR package.
Seeing life in black and white
Turns out there is a lot of different ways to turn colors into grayscale. Prismatic has implemented a handful of these. Notice how the viridis palette is still working once you have it transformed to black and white.
hcl.colors(10) %>%
clr_greyscale() %>%
plot()
Be advised that not all of these methods are meant to be perceptually uniform.
Negate
Negation of color is pretty simple. it will just pick the opposite color in RGB space.
terrain.colors(10) %>%
clr_negate() %>%
plot()
Mixing
Mixing is just adding colors together. Thus my mixing a color with red would make the color redder.
rainbow(10) %>%
clr_mix("red") %>%
plot()
Rotation
the clr_rotate()
function will take a color and rotate its hue, which is a way to walk around the rainbow.
terrain.colors(10) %>%
clr_rotate(90) %>%
plot()
Colorblindness
also includes 3 functions (clr_protan()
, clr_deutan()
and clr_tritan()
) to simulate colorblindness. These functions has a severity
argument to control the strength of the deficiency.
hcl.colors(10) %>%
clr_deutan() %>%
plot()
Light and darkness
Lastly, we have functions to simulate lightness and darkness. This is surprisingly hard to do and no one way works great all the time. Please refer to the excellent colorspace paper for more information. These functions (clr_lighten()
and clr_darken()
) also include a space
argument to determine the space in which to perform the transformation. Please try each of these to find the optimal method for your use case.
rainbow(10) %>%
clr_darken() %>%
plot()
Comparison Code
swatchplot(
list(
saturate = rbind("0" = clr_rotate(terrain.colors(10), 0),
"60" = clr_rotate(terrain.colors(10), 60),
"120" = clr_rotate(terrain.colors(10), 120),
"180" = clr_rotate(terrain.colors(10), 180),
"240" = clr_rotate(terrain.colors(10), 240),
"300" = clr_rotate(terrain.colors(10), 300)),
desaturate = rbind("0" = clr_rotate(hcl.colors(10), 0),
"60" = clr_rotate(hcl.colors(10), 60),
"120" = clr_rotate(hcl.colors(10), 120),
"180" = clr_rotate(hcl.colors(10), 180),
"240" = clr_rotate(hcl.colors(10), 240),
"300" = clr_rotate(hcl.colors(10), 300))
),nrow = 7, line = 2.5
)
session information
─ Session info ───────────────────────────────────────────────────────────────
setting value 4.1.0 (2021-05-18)
version R version 10.16
os macOS Big Sur .0
system x86_64, darwin17
ui X11 language (EN)
-8
collate en_US.UTF-8
ctype en_US.UTF/Los_Angeles
tz America2021-07-16
date
─ Packages ───────────────────────────────────────────────────────────────────* version date lib
package 1.3.2 2021-06-09 [1]
blogdown 0.22 2021-04-22 [1]
bookdown 0.2.5.1 2021-05-18 [1]
bslib 3.0.0 2021-06-30 [1]
cli 0.7.1 2020-10-08 [1]
clipr 0.2-18 2020-11-04 [1]
codetools * 2.0-2 2021-06-24 [1]
colorspace 1.4.1 2021-02-08 [1]
crayon 1.3.0 2021-03-05 [1]
desc * 0.2.1 2020-01-12 [1]
details 0.6.27 2020-10-24 [1]
digest 0.14 2019-05-28 [1]
evaluate 2.1.0 2021-02-28 [1]
farver 0.9 2021-04-16 [1]
highr 0.5.1.1 2021-01-22 [1]
htmltools 1.4.2 2020-07-20 [1]
httr 0.1.4 2021-04-26 [1]
jquerylib 1.7.2 2020-12-09 [1]
jsonlite * 1.33 2021-04-24 [1]
knitr 0.1.0 2021-07-17 [1]
LaCroixColoR * 2.0.1 2020-11-17 [1]
magrittr 0.1-7 2013-12-03 [1]
png * 1.0.0 2021-01-05 [1]
prismatic 2.5.0 2020-10-28 [1]
R6 0.4.11 2021-04-30 [1]
rlang 2.9 2021-06-15 [1]
rmarkdown 2.0.2 2020-11-15 [1]
rprojroot 0.4.0 2021-05-12 [1]
sass 1.1.1 2018-11-05 [1]
sessioninfo 1.6.2 2021-05-17 [1]
stringi 1.4.0 2019-02-10 [1]
stringr 2.4.2 2021-04-18 [1]
withr 0.24 2021-06-15 [1]
xfun 1.3.2 2020-04-23 [1]
xml2 2.2.1 2020-02-01 [1]
yaml
source Github (rstudio/blogdown@00a2090)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
Github (johannesbjork/LaCroixColoR@57e6c09)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
CRAN (R 4.1.0)
1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library [