---
title: "Colors and color functions"
author: "SPDS, uni.kn"
date: "2023 07 28"
output:
rmarkdown::html_vignette:
fig_caption: yes
vignette: >
%\VignetteIndexEntry{Colors and color functions}
%\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown}
editor_options:
chunk_output_type: console
---
```{r setup, include = FALSE}
options(max.print = "75")
knitr::opts_chunk$set(echo = TRUE,
cache = FALSE,
collapse = TRUE,
comment = "#>",
prompt = FALSE,
tidy = FALSE,
message = FALSE,
warning = FALSE,
# Default figure options:
fig.align = "center",
# fig.width = 6,
# fig.asp = .8 # .618, # golden ratio
out.width = "60%")
```
This vignette explains the colors, color palettes, and color-related functions provided by the **unikn** package.
(See the vignettes on [color recipes](color_recipes.html) and [institutional colors](inst_colors.html) for more specialized tasks
and the vignette on [text](text_decorations.html) for information on text boxes and decorations.)
Please install and/or load the **unikn** package to get started:
```{r load-pkg-colors, message = FALSE, warning = FALSE}
# install.packages('unikn') # install unikn from CRAN client
library('unikn') # loads the package
```
## Overview
The **unikn** package provides some colors (e.g., `Seeblau`) and color palettes (e.g., `pal_unikn`).
However, its functionality is mainly based on color-related functions that are useful beyond the colors and palettes of this package.
The package provides two main functions for interacting with color palettes: `seecol()` and `usecol()`.
1. `seecol()` is a general-purpose tool for **seeing (inspecting or visualizing) colors or color palettes**.
The `seecol()` function takes two main arguments:
- `pal` provides either one or multiple color palettes (with a default of `pal = "unikn_all"`);
- `n` specifies the number of desired colors (with a default of `n = "all"`).
Based on the input of `pal`, the `seecol()` function distinguishes between two modes:
- A. _viewing the details_ of a _single_ color palette (when providing only one color palette);
- B. _comparing multiple_ color palettes (when providing a keyword or `list`-object).
2. `usecol()` allows **using colors or color palettes** (e.g., when creating visualizations) without showing its details.
The `usecol()` function also takes arguments for conveniently manipulating color palettes:
- `pal` provides either one or multiple color palettes (with a default of `pal = pal_unikn`);
- `n` specifies the number of desired colors (with a default of `n = "all"`);
- `alpha` adjusts the opacity of all colors in `pal` (e.g., `alpha = .50` for medium transparency).
Two additional functions allow **finding colors** by similarity or name:
1. `simcol()` allows **finding similar colors** (given a target color, a set of candidate colors, and some tolerance threshold(s));
2. `grepal()` allows **finding colors with particular names** (i.e., colors whose names match some `pattern` or regular expression);
Finally, some **auxiliary functions** support specific color functions:
- `ac()` adjusts **color transparency**;
- `shades_of()` allows creating **linear color gradients**;
- `newpal()` allows **defining new color palettes** (as vectors or data frames with dedicated color names); and
- `demopal()` allows **illustrating color palettes** for different types of visualizations.
The rest of this vignette provides examples of and some details on using these functions.
(See the [Color recipes](color_recipes.html) vignette for more examples of solving color-related tasks.)
## Viewing colors and color palettes with `seecol()`
The behavior of the `seecol()` function distinguishes between two modes and depends on the input to its initial `pal` argument.
It either shows (A)\ the details of an individual color palette, or (B)\ allows comparing multiple color palettes.
The next two sections will address both modes in turn.
### A. Viewing details of a single color palette
When the `pal` argument of the `seecol()` function specifies a _single_ color palette, the function plots a more detailed view of this particular color palette:
```{r unikn-palette, fig.width = 5, fig.asp = .8, fig.align = 'center'}
seecol(pal_unikn) # view details of pal_unikn
```
The detailed overview of a color palette provides us with
- the color names (where available),
- their numeric indices (within the color palette),
- the HEX values for each color,
- the RGB values for each color.
When a color palette contains too many colors, the HEX and RGB values are no longer printed.
However, setting `hex` and `rgb` to\ TRUE will force them to be shown.
Note that `seecol()` also returns the color palette that is being shown.
Thus, a typical workflow comprises both _seeing_ a particular color palette and _saving_ it (for storing and applying it later):
```{r save-seecol, fig.width = 5, fig.asp = .8, fig.align = 'center'}
my_pal <- seecol(pal_unikn_light) # view details of AND save a color palette
```
Due to saving the color palette (here to `my_pal`) we can later use it in a visualization:
```{r my-pal-example, fig.width = 5, fig.asp = .65, fig.align = 'center'}
barplot(1/sqrt(1:10), col = my_pal) # use my_pal in a plot
```
Note that `seecol()` _invisibly_ returns the color palette.
Thus, the following will plot the palette `pal_bordeaux` without doing anything else with it:
```{r invisible-seecol, fig.width = 5, fig.asp = .8, fig.align = 'center'}
seecol(pal_bordeaux)
```
but the following would both plot and assign the palette to `my_pal`:
```{r invisible-seecol-assign, eval = FALSE}
my_pal <- seecol(pal_bordeaux)
```
### B. Viewing and comparing multiple color palettes
The second mode of `seecol()` is invoked by providing (a list of) _multiple_ color palettes to its `pal` argument.
In this case, the function allows comparing these palettes by plotting a color vector for each palette.
Some special keywords within the **unikn** package denote sets of color palettes:
- The keywords `"unikn_all"`, `"unikn_basic"`, `pair_all"`, `"pref_all"` and `"grad_all"` refer to [University of Konstanz](https://www.uni-konstanz.de/) color palettes.
Calling `seecol` with `pal` set to these keywords allows comparing pre-defined sets of the color palettes:
Viewing the [uni.kn](https://www.uni-konstanz.de/) color palettes:
```{r seecol-unikn-all, fig.width = 6, fig.height = 5, fig.align = 'center'}
seecol("unikn_all") # all uni.kn color palettes
```
1. three _basic_ color palettes:
```{r seecol-unikn-basic-2, fig.width = 6, fig.height = 2, fig.align = 'center'}
seecol("unikn_basic")
```
Note, that `pal_unikn_web` and `pal_unikn_ppt` are almost identical, but differ in how vibrant their colors are.
2. three _paired_ color palettes:
```{r seecol-pair-all, fig.width = 6, fig.height = 2.5, fig.align = 'center'}
seecol("pair_all")
```
3. all _preferred_ colors from the spectrum and their respective _gradients_:
```{r seecol-pref-all, fig.width = 6, fig.height = 3.5, fig.align = 'center', out.width="500"}
seecol("pref_all")
```
4. only the pre-defined color _gradients_:
```{r seecol-grad-all-2, fig.width = 5, fig.asp = .8, fig.align = 'center', out.width="400"}
seecol("grad_all")
```
```{r seecol-add, echo = FALSE, eval = FALSE, fig.width = 7.2, fig.asp = .9, fig.align = 'center', out.width="500"}
seecol("add")
```
See the vignette on [Institutional colors](inst_colors.html) for creating color palettes for other institutions.
### Other `seecol()` arguments
The `seecol()` function provides some aesthetic parameters for adjusting how color palettes are plotted:
- `col_brd` allows specifying the color of box borders (if shown. Default: `col_brd = NULL`);
- `lwd_brd` allows specifying the line width of box borders (if shown. Default: `lwd_brd = NULL`);
- `main` and `sub` allow replacing the default titles with custom titles.
Examples:
```{r seecol-aesthetic-parameters, fig.width = 5, out.width = "60%", fig.asp = .8, fig.align = 'center', out.width="400"}
seecol("grad_all", col_brd = "black", lwd_brd = .5, main = "Color gradients (with black borders)")
seecol(pal_seegruen, col_brd = "white", lwd_brd = 5, main = "A color palette (with white borders)")
```
## Using a color palette with `usecol()`
The `usecol()` function allows directly using a color palette in a plot (i.e., without first viewing it).
`usecol()` corresponds to `seecol()` by taking the same main arguments (`pal` and `n`).
However, as its purpose is _using_ the colors specified by `pal`, rather than plotting (or _seeing_) them, its `pal`\ argument typically contains only one color palette:
```{r usecol-default-use, fig.width = 5, out.width = "60%", fig.asp = .65, fig.align = 'center'}
# Using a color palette:
barplot(1/sqrt(1:11), col = usecol(pal_unikn))
```
Note that the `seecol()` and `usecol()` functions are both quite permissive with respect to specifying their `pal` argument:
A particular color palette (e.g., `pal_seegruen`) can not only be displayed by providing it (as an object) but also by providing its name (i.e., `"pal_seegruen"`) or even an incomplete object name or name (i.e., `"seegruen"` or `seegruen`).
Hence, the following expressions all yield the same result:
```{r free-pal-args, fig.width = 5, fig.asp = .75, eval = FALSE}
seecol(pal_seegruen)
seecol("pal_seegruen")
seecol("seegruen")
seecol(seegruen) # issues a warning, but works
```
## Customizing color palettes
Both the `seecol()` and the `usecol()` functions allow a flexible on-the-fly customization of color palettes.
Specifying a value for the `n` argument of `seecol()` an `usecol()` allows:
- specifying subsets of colors and comparing these subsets for different palettes for `n` _smaller_ than the length of the color palette;
- extending color palettes and comparing different palettes for `n` _greater_ than the length of the color palette.
Passing a vector of colors and/or color palettes allows users to create and view their own color palettes.
Finally, specifying a value for `alpha` (in a range from 0 to 1) allows controlling the transparency of the color palette(s), with higher values for `alpha` corresponding to higher transparency (i.e., lower opacity).
### Selecting subsets
Using only a subset of colors:
```{r use-subset, fig.width = 5, fig.height = 4, fig.align = 'center', collapse = TRUE}
seecol("unikn_all", n = 4)
seecol(pal_unikn, 4)
```
Importantly, when using pre-defined color palettes of **unikn** but a value of `n` that is smaller than the length of the current color palette, `usecol` and `seecol` select a predefined subset of colors:
```{r use-col-small-n, fig.width = 3, out.width = c('35%', '35%'), fig.height = 2.5, fig.align = 'center', collapse = TRUE, fig.show = 'hold'}
barplot(1/sqrt(1:2), col = usecol(pal_seeblau, n = 2))
barplot(1/sqrt(1:3), col = usecol(pal_seeblau, n = 3))
```
### Extending color palettes
For values of `n` that are larger than the number of available colors in `pal`, the specified color palette is extended using `ColorRampPalette`:
```{r use-superset-all, fig.width = 5, fig.asp = .8, fig.align = 'center', collapse = TRUE}
seecol("unikn_all", n = 12)
```
Both `seecol()` and `usecol()` allow extending or truncating color palettes to a desired number `n` of colors.
For instance:
- Inspecting an extended version of `pal_seeblau` (with `n = 8` colors):
```{r use-superset, eval = FALSE, fig.width = 5, fig.asp = .8, fig.align = 'center', collapse = TRUE}
seecol(pal_seeblau, n = 8)
```
- Using a truncated version of `pal_bordeaux` (with `n = 3` colors):
```{r use-col-big-n, eval = FALSE, fig.width = 5, fig.asp = .65, fig.align = 'center'}
barplot(1/sqrt(1:9), col = usecol(pal_bordeaux, n = 3))
```
### Mixing colors and color palettes
By passing a vector to `pal`, we can concatenate 2 color palettes and connect them with a color (here: `"white"`) as the midpoint of a new color palette:
```{r combine-pals, fig.width = 5, out.width = "60%", fig.asp = .8, fig.align = 'center'}
seecol(pal = c(rev(pal_petrol), "white", pal_bordeaux))
```
We can combine a set of colors and extend this palette by specifying an `n` argument that is larger than the length of the specified palette:
```{r combine-pals-n, fig.width = 5, out.width = "60%", fig.asp = .8, fig.align = 'center'}
seecol(pal = usecol(c(Karpfenblau, Seeblau, "gold"), n = 10))
```
These custom palettes can easily be used in a plot. For instance, we can define and use a subset of the `pal_unikn_pair` palette as follows:
```{r use-my-pair, fig.width = 5, fig.height = 4, fig.align = 'center'}
my_pair <- seecol(pal_unikn_pair, n = 10)
# Create data:
dat <- matrix(sample(5:10, size = 10, replace = TRUE), ncol = 5)
# Plot in my_pair colors:
barplot(dat, beside = TRUE, col = my_pair)
```
Creating linear color gradients is also supported by the `shades_of()` function (see below).
### Controlling transparency
Both `seecol()` and `usecol()` accept an `alpha` argument (in a range from\ 0 to\ 1) for controlling the transparency of color palettes, with higher values for `alpha` corresponding to lower transparency (i.e., higher opacity).
Displaying a specific color palette at a medium opacity/transparency:
```{r transparency1-pal, fig.width = 5, fig.asp = .8, fig.align = 'center', collapse = TRUE}
seecol(pal_unikn, alpha = 0.5)
```
Setting opacity for a custom color palette:
```{r transparency-four, fig.width = 5, fig.asp = .8, fig.align = 'center'}
four_cols <- usecol(c("steelblue", "gold", "firebrick", "forestgreen"), alpha = 2/3)
seecol(four_cols, main = "Four named colors with added transparency")
```
Setting opacity for comparing of multiple color palettes:
```{r transparency-all, fig.width = 5, fig.height = 4, fig.align = 'center'}
seecol("grad", alpha = 0.67, main = "Seeing transparent color palettes")
```
### Creating and comparing custom palettes
Suppose we want to compare a newly created color palette to existing color palettes. To achieve this, advanced users can use the `seecol()` function for displaying and comparing different custom palettes. When provided with a list of color palettes as the input to its `pal` argument, `seecol()` will show a _comparison_ of the inputs:
```{r compare-custom-palettes, fig.width = 5, fig.height = 3, fig.align = 'center'}
# Define 2 palettes:
pal1 <- c(rev(pal_seeblau), "white", pal_bordeaux)
pal2 <- usecol(c(Karpfenblau, Seeblau, "gold"), n = 10)
# Show the my_pair palette from above, the 2 palettes just defined, and 2 pre-defined palettes:
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair))
```
Note that unknown color palettes are named `pal_`$n$, in increasing order.
Palettes known to `seecol()` are labeled by their respective names.
Labeling only custom palettes works by setting the `pal_names` argument to a character vector of appropriate length:
```{r set-custom-palette-names, eval = FALSE, fig.width = 5, fig.height = 3, fig.align = 'center'}
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair),
pal_names = c("my_pair", "blue_bord", "blue_yell"),
main = "Labeling custom color palettes")
```
If the `pal_names` argument is specified and corresponds to the length of _all_ color palettes, the default names of all color palettes are overwritten by `pal_names`:
```{r set-all-palette-names, eval = FALSE, fig.width = 5, fig.height = 3, fig.align = 'center'}
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair),
pal_names = c("my_pair", "blue_bord", "blue_yell", "blue_black", "mix_pair"),
main = "Comparing and labeling custom color palettes")
```
As before, we can use lower values of `n`\ for truncating/obtaining shorter subsets of color palettes:
```{r subset-compare, fig.width = 5, fig.height = 3, fig.align = 'center'}
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair), n = 5)
```
or higher values of\ `n` for extending color palettes:
```{r superset-compare, fig.width = 5, fig.height = 3, fig.align = 'center'}
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair), n = 15)
```
## Finding colors
Two familiar color search tasks are addressed by the `simcol()` and `grepal()` functions:
- `simcol()` allows searching for colors that are similar to a given target color
- `grepal()` allows searching for colors whose names match some pattern
### Finding similar colors with `simcol()`
Assuming that our favorite color is `"deeppink"`, a good question is: How can we find similar colors?
Given some target color, the `simcol()` function searches through a set of colors to find and return visually similar ones:
```{r simcol-1, fig.width = 5, fig.asp = .8, fig.align = 'center', fig.show = 'hold'}
simcol("deeppink", plot = FALSE)
```
By default, `simcol()` searches though all named R\ colors of `colors()` (of the **grDevices** package), but adjusting the `col_candidates` and `tol` arguments allows for more fine-grained searches:
```{r simcol-2, fig.width = 5, out.width = "60%", fig.asp = .8, fig.align = 'center', fig.show = 'hold'}
simcol("deepskyblue", col_candidates = pal_seeblau, tol = c(50, 50, 100))
```
### Finding color names with `grepal()`
We often search for some particular color hue (e.g., some sort of purple), but also know that the particular color named "purple" is _not_ the one we want.
Instead, we would like to see all colors that contain the keyword "purple" in its name.
The `grepal()` function addresses this need:
```{r grepal-1, fig.width = 6, out.width = "60%", fig.height = 4, fig.align = 'center'}
grepal("purple") # get & see 10 names of colors() with "purple" in their name
```
Note that the `grepal()` function allows searching color names by regular expressions:
```{r grepal-2}
length(grepal("gr(a|e)y", plot = FALSE)) # shades of "gray" or "grey"
length(grepal("^gr(a|e)y", plot = FALSE)) # shades starting with "gray" or "grey"
length(grepal("^gr(a|e)y$", plot = FALSE)) # shades starting and ending with "gray" or "grey"
```
By default, `grepal()` searches the vector of named colors `x = colors()` (of the **grDevices** package) and plots its results (as a side effect).
However, it also allows for searching color palettes provided as data frames (with color names) and for suppressing the visualization (by setting `plot = FALSE`):
```{r grepal-3, fig.width = 5, out.width = "60%", fig.asp = .8, fig.align = 'center'}
grepal("see", pal_unikn) # finding "see" in (the names of) pal_unikn (as df)
grepal("blau", pal_unikn_pref, plot = FALSE) # finding "blau" in pal_unikn_pref
```
## Auxiliary color functions
### Adjusting transparency with `ac()`
The `ac()` function provides a flexible wrapper around the `adjustcolor()` function of the **grDevices** package.
Its key functionality is that it allows for _vectorized_\ `col` and\ `alpha` arguments:
```{r transparency-ac, fig.width = 5, fig.asp = .8, fig.align = 'center'}
my_cols <- c("black", "firebrick", "forestgreen", "gold", "steelblue")
seecol(ac(my_cols, alpha = c(rep(.25, 5), rep(.75, 5))))
```
The name `ac` is an abbreviation of "adjust color", but also a mnemonic aid for providing "air conditioning".
### Creating color gradients with `shades_of()`
We have seen that the main `usecol()` function allows stretching and squeezing color palettes and thus creating complex color gradients.
An even simpler way for creating linear color gradients is provided by the `shades_of()` function:
```{r shades-of-1, fig.width = 4.5, fig.asp = .8, fig.align = 'center'}
seecol(shades_of(n = 5, col_1 = Karpfenblau), main = "5 shades of Karpfenblau")
```
Internally, `shades_of()` is just a convenient wrapper for a special `usecol()` function.
The limitation of `shades_of()` is that it only allows creating bi-polar color palettes (i.e., gradients between two colors).
When the final color `col_n` is unspecified, its default of "white" is used (as in the example).
By contrast, the `usecol()` function allows creating color gradients between an arbitrary number of colors.
Thus, the following two expressions define the same bi-polar color palette:
```{r shades-of-2, fig.width = 5, fig.asp = .8, fig.align = 'center'}
pg_1 <- usecol(c("deeppink", "gold"), 5)
pg_2 <- shades_of(5, "deeppink", "gold")
all.equal(pg_1, pg_2)
seecol(pg_2, main = "A bi-polar color gradient")
```
### Defining color palettes with `newpal()`
Having created, combined or found all those beautiful colors, we may wish to define a new color palette.
Defining a new named color palette allows to consistently access and apply colors (e.g., to a series of visualizations in a report or publication).
The `newpal()` function makes it easy to define color palettes:
```{r newpal-1, fig.width = 5, fig.asp = .8, fig.align = 'center'}
col_flag <- c("#000000", "#dd0000", "#ffce00") # source: www.schemecolor.com
flag_de <- newpal(col = col_flag,
names = c("black", "red", "gold"))
seecol(flag_de, main = "Defining a flag_de color palette")
```
By default, `newpal()` returns the new color palette as a (named) vector. Setting `as_df = TRUE` returns a data frame.
### Illustrating color palettes with `demopal()`
After choosing, creating or modifying a color palette, we usually inspect the result with `seecol()`.
Alternatively, we can use the `demopal()` function to use a color palette\ `pal` in a visualization.
Currently, the `type` argument supports the following visualizations:
1. "bar": A bar plot
2. "curve": A plot of normal distribution curves (with transparency)
3. "mosaic": A mosaic/table plot
4. "polygon": An area/polygon plot
5. "scatter": A scatter plot of points (with transparency)
All types of `demopal()` invisibly return their (randomly generated) data and accept some graphical arguments (e.g., `col_par` and `alpha`), a scaling `n` and a `seed` value (for reproducible results), as well as `main` and `sub` arguments (for setting plot titles).
Some functions additionally accept type-specific arguments (e.g., logical `beside`, `horiz`, and `as_prop` arguments for plot `type = "bar"`).
```{r demopal, fig.width = 5, fig.asp = .8, fig.align = 'center'}
demopal(pal = pg_2, type = 3)
```
This concludes our quick tour through the colors and color functions of the **unikn** package.
We hope that they enable you to find, design, and use beautiful color palettes ---\ and spice up your visualizations by vivid and flamboyant colors!
## Resources
The following versions of **unikn** and corresponding resources are currently available:
Type: | Version: | URL: |
:------------------------|:-------------------|:-------------------------------|
A. **unikn** (R package): | [Release version](https://CRAN.R-project.org/package=unikn) | |
| [Development version](https://github.com/hneth/unikn/) | |
B. Online documentation: | [Release version](https://hneth.github.io/unikn/) | |
| [Development version](https://hneth.github.io/unikn/dev/) | |
## Vignettes
The following vignettes provide instructions and examples for using the **unikn** colors, color palettes, and functions:
| Nr. | Vignette | Content |
| ---: |:---------|:-----------|
| 1. | [Colors](color_functions.html) | Colors and color functions |
| 2. | [Color recipes](color_recipes.html) | Recipes for color-related tasks |
| 3. | [Institutional colors](inst_colors.html) | Creating color palettes for other institutions |
| 4. | [Text](text_decorations.html) | Text boxes and decorations |