--- 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%") ``` unikn:: 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: unikn:: | 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 |