---
title: "Colors and color functions"
author: "SPDS, uni.kn"
date: "2020 12 18"
output: 
  rmarkdown::html_vignette: 
    fig_caption: yes
vignette: > 
  %\VignetteIndexEntry{Colors}
  %\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,
               prompt = FALSE,
               tidy = FALSE,
               collapse = TRUE, 
               comment = "#>",
               message = FALSE,
               warning = FALSE,
               ## Default figure options:
               # fig.width = 6, 
               # fig.asp = .8 # .618, # golden ratio
               # out.width = "75%",
               fig.align = "center"
               )
```

<!-- unikn pkg logo and link: -->
<a href = "https://github.com/hneth/unikn/">
<img src = "../inst/pix/unikn.png" alt = "unikn::" align = "right" width = "140px" style = "width: 140px; float: right; border:0;"/>
</a>

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](color_inst.html) for more specialized tasks 
and the vignette on [text](text.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 mainly comes from color-related functions that are useful beyond the dedicated colors 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 viewing (or _seeing_) color palettes. 
The `seecol()` function takes two main arguments:

    1. `pal` provides either one or multiple color palettes (with a default of `pal = "all"`);  
    2. `n` specifies the number of desired colors (with a default of `n = "all"`).  

Based on the setting of `pal`, the `seecol()` function distinguishes between two modes: 

    * _comparing_ a set of multiple color palettes (by passing a keyword or `list`-object);  
    * viewing the _details_ of a single color palette (by providing only one palette).   

2. `usecol()` allows using a color palette (e.g., when creating visualizations) without showing its details. 
The `usecol()` function also takes arguments for conveniently manipulating color palettes:

    1. `pal` provides either one or multiple color palettes (with a default of `pal = pal_unikn`);  
    2. `n` specifies the number of desired colors (with a default of `n = "all"`); 
    3. `alpha` adjusts the opacity of all colors in `pal` (e.g., `alpha = .50` for medium transparency). 


Two additional functions serve in auxiliary roles: 

1. `newpal()` allows defining new color palettes (typically as data frames with dedicated color names). 

2. `grepal()` searches a color palette\ `x` (i.e., a vector of color names or data frame of named colors) for a `pattern` and returns those that match the pattern (or regular expression). 


## Viewing colors and color palettes with `seecol()`

The behavior of the `seecol()` function depends on the inputs to its `pal` argument. 
It either allows comparing multiple color palettes or shows the details of a single color palette.

### Viewing and comparing available color palettes

When the `pal` argument specifies (a list of) multiple color palettes, `seecol()` plots a vector for each palette to allow comparing these palettes. 
Some special keywords within the **unikn** package denote sets of color palettes: `"unikn_all"`, `"unikn_basic"`, `pair_all"`, `"pref_all"` and `"grad_all"`. Calling `seecol` with `pal` set to these keywords allows comparing pre-defined sets of the color palettes:   

Viewing _all_ available color palettes:

```{r seecol-unikn-all, fig.width = 6, fig.height = 5, fig.align = 'center'}
seecol("unikn_all")  # same as seecol("all")
```

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'}
seecol("pref_all")
```

4. only the pre-defined color _gradients_:

```{r seecol-grad-all-2, fig.width = 5, fig.asp = .8, fig.align = 'center'}
seecol("grad_all")
```

### Viewing and saving a 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 single 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.  

A typical workflow comprises first _seeing_ a color palette, then saving it, and using it in a plot.  

```{r save-seecol, fig.width = 5, fig.asp = .8, fig.align = 'center'}
my_pal <- seecol(pal_unikn_light)  # view details of AND save pal_unikn_light to my_pal  
```

After saving the color palette you can use the palette object in your plot: 

```{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 only plot the palette without doing anything else with the color vector:

```{r invisible-seecol, fig.width = 5, fig.asp = .8, fig.align = 'center'}
seecol(pal_bordeaux)
```

### Other parameters of `seecol()`

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`);   
- `title` allows replacing the default title with a custom title.  

Examples:

```{r seecol-aesthetic-parameters, fig.width = 5, fig.asp = .8, fig.align = 'center'}
seecol("grad_all", col_brd = "black", lwd_brd = 1, title = "Color gradients (with black borders)")
seecol(pal_seegruen, col_brd = "white", lwd_brd = 10, title = "A color palette (with white borders)")
```


## Using a color palette with `usecol()` (without seeing it)

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, fig.asp = .65, fig.align = 'center'}
# Using a color palette:
barplot(1/sqrt(1:11), col = usecol(pal_unikn))
```

<!-- Flexibility in providing color palette pal: -->

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 flexible on-the-fly customizations 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, 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("all", n = 12)
```

```{r use-superset, fig.width = 5, fig.asp = .8, fig.align = 'center', collapse = TRUE}
seecol(pal_seeblau, 12)
```

When using a color palette: 

```{r use-col-big-n, fig.width = 5, fig.asp = .65, fig.align = 'center'}
barplot(1/sqrt(1:11), col = usecol(pal_bordeaux, n = 11))
```

### Mixing 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, 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, fig.asp = .8, fig.align = 'center'}
seecol(pal = usecol(c(Karpfenblau, Seeblau, "gold"), n = 10))
# Note, that redundant use of seecol and usecol shows HEX values as names.
# seecol(pal = c(Karpfenblau, Seeblau, "gold"), n = 10)  # would work, but show no intermediate names
```

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)
```

### 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, title = "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, title = "Seeing color palettes with added transparency")
```

### 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, 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"),
       title = "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, 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"),
       title = "Comparing and labeling custom color palettes")
```

As before, we can use the `n`\ argument for 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 larger 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)
```


## Defining new color palettes with `newpal()`

The `newpal()` function makes it easy to define new named 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, title = "Defining a flag_de color palette")
```

By default, `newpal()` returns the new color palette as a data frame. 
Setting `as_df = FALSE` returns a (named) vector. 


## Searching for color names with `grepal()` 

A common situation in R is that we want some particular shade of color (e.g., some sort of red), but also know that the color named "red" is _not_ the one we want. Instead, we would like to see all colors that contain "red" in its name. This is what `grepal()` is made for:

```{r grepal-1, fig.width = 6, fig.height = 4, fig.align = 'center'}
grepal("red")  # get 27 names of colors() with "red" in their name

seecol(grepal("red"))  # see all colors() with "red" in their name
```

Note that the `grepal()` allows for regular expressions:

```{r grepal-2}
length(grepal("gr(a|e)y"))   # shades of "gray" or "grey"
length(grepal("^gr(a|e)y"))  # shades starting with "gray" or "grey"
length(grepal("^gr(a|e)y$")) # shades starting and ending with "gray" or "grey"
```

By default, `grepal()` searches the vector of named colors `x = colors()` (provided by **grDevices**). 
However, it also allows searching color palettes provided as data frames (with color names):

```{r grepal-3, fig.width = 5, fig.asp = .8, fig.align = 'center'}
grepal("see", pal_unikn)

seecol(grepal("blau", pal_unikn_pref), title = "Shades of 'blau' in pal_unikn_pref")
```


## 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) | <https://CRAN.R-project.org/package=unikn> |
    &nbsp;                | [Development version](https://github.com/hneth/unikn/)      | <https://github.com/hneth/unikn/> | 
B. Online documentation:  | [Release version](https://hneth.github.io/unikn/)           | <https://hneth.github.io/unikn/> | 
    &nbsp;                | [Development version](https://hneth.github.io/unikn/dev/)   | <https://hneth.github.io/unikn/dev/> | 


## Vignettes

<!-- unikn pkg logo and link: -->
<a href = "https://github.com/hneth/unikn/">
<img src = "../inst/pix/unikn.png" alt = "unikn::" align = "right" width = "140px" style = "width: 140px; float: right; border:0;"/>
</a> 

The following vignettes provide instructions and examples for using the **unikn** colors, color palettes, and functions: 

<!-- Table of vignettes: -->

| Nr.  | Vignette | Content    |        
| ---: |:---------|:-----------|
| 1. | [Colors](colors.html) | Colors and color functions |
| 2. | [Color recipes](color_recipes.html) | Recipes for color-related tasks |
| 3. | [Institutional colors](color_inst.html) | Creating color palettes for other institutions |
| 4. | [Text](text.html)     | Text boxes and decorations | 

<!-- eof. -->