---
title: "Colors and color palettes"
author: "SPDS, uni.kn"
date: "2019 06 14"
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 = 7.2, 
               # fig.asp = .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 which colors and color palettes are provided by **unikn** and how they can be accessed and used. 
(See 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')             # load the package
```

## Overview 

There are 2 functions to interact with the color palettes in the **unikn** package: `seecol()` and `usecol()`. 

1. The `seecol()` function is a general-purpose tool for viewing (or _seeing_) color palettes. `seecol` takes 2 main arguments:

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

Based on the setting of `pal`, the `seecol` function distinguishes between 2 modes: 

* _comparing_ a set of color palettes by passing a keyword or `list`-object;  
* viewing the _details_ of a single color palette.   

2. The `usecol()` function allows using a color palette without showing its details. 


## Viewing and comparing available color palettes

The `seecol()` function shows multiple or the details of a single color palette. 
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 = 7, fig.height = 6, fig.align = 'center'}
seecol("unikn_all")  # same as seecol("all")
```

1. three _basic_ color palettes:

```{r seecol_unikn_basic_2, fig.width = 7, fig.height = 2.5, 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 = 7, 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 = 7, fig.height = 4, fig.align = 'center'}
seecol("pref_all")
```

4. only the pre-defined color _gradients_:

```{r seecol_grad_all_2, fig.width = 7, fig.height = 3.5, 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 = 6, fig.asp = .75, fig.align = 'center'}
seecol(pal_unikn)  # view details of pal_unikn 
```

In the detailed overview, we _see_ 

- the color names (where available),  
- numeric indices of the color palette,   
- the HEX values of each color,   
- the RGB values for each color.  

A typical workflow may include _seeing_ a color palette, saving it, and using it in a plot.  

```{r save_seecol, fig.width = 6, fig.asp = .75, 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 = 6, fig.asp = .618, 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 = 6, fig.asp = .75, fig.align = 'center'}
seecol(pal_bordeaux)
```

## Using a 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 2 main arguments (`pal` and `n`). 
However, as its purpose is _using_ the colors specified by `pal`, rather than plotting (or _seeing_) them, the `pal` argument typically contains only 1&nbsp;color palette:  

```{r use_col_default_use, fig.width = 6, fig.asp = .618, fig.align = 'center'}
# Using a color palette:
barplot(1/sqrt(1:11), col = usecol(pal_unikn))
```

Note that the both the `seecol` and the `usecol` function are 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 its incomplete object name or name (i.e., `"seegruen"` or `seegruen`). 
Hence, the following all yield the same result: 

```{r free_pal_args, fig.width = 6, fig.asp = .75, eval = FALSE}
seecol(pal_seegruen)
seecol("pal_seegruen")
seecol(seegruen)  # issues a warning
seecol("seegruen")
```

## 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 you creating and viewing your own 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 = 6, fig.height = 5, 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_smalln, fig.width = 3.5, fig.height = 3, 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 = 7, fig.height = 6, fig.align = 'center', collapse = TRUE}
seecol("all", n = 12)
```

```{r use_superset, fig.width = 6, fig.asp = .75, fig.align = 'center', collapse = TRUE}
seecol(pal_seeblau, 12)
```

When using a color palette: 

```{r use_col_big_n, fig.width = 6, fig.asp = .618, 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 = 6, fig.asp = .75, 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 = 6, fig.asp = .75, 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 = 6, 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 higher transparency (i.e., lower opacity).

Displaying a specific color palette at an opacity of 0.5:

```{r transparency1_pal, fig.width = 6, fig.asp = .75, fig.align = 'center', collapse = TRUE}
seecol(pal_unikn, alpha = 0.5)
```

Setting opacity for comparing of multiple color palettes: 

```{r transparency_all, fig.width = 6, fig.height = 3, fig.align = 'center'}
seecol("grad", alpha = 0.67)
```


### 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 = 6, 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 will be named `pal`n in increasing order. Palettes known to `seecol()` will be shown with their respective names.  

As before, we can use the `n` argument for obtaining shorter subsets of color palettes: 

```{r subset_compare, fig.width = 6, 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 = 6, fig.height = 3, fig.align = 'center'}
seecol(list(my_pair, pal1, pal2, pal_unikn, pal_unikn_pair), n = 15)
```


## Examples

The following examples illustrate how plotting functions in R can use the **unikn** color palettes and the `seecol()` and `usecol()` functions. 

1. Using the `plot` function of **base R** for a scatterplot: 

```{r demo_scatterplot, eval = TRUE, fig.width = 5, fig.height = 5, fig.align = 'center', collapse = TRUE}
plot(x = runif(99), y = runif(99), "p", pch = 16, cex = 4, 
     col = usecol(pal_unikn, alpha = .50),  # with transparency
     main = "99 transparent dots", axes = FALSE, xlab = NA, ylab = NA)
```

2. Using the `ggplot` function of **ggplot2** for an area plot: 

```{r use_pal_ggplot2, eval = FALSE, fig.width = 7, fig.asp = .618, fig.align = 'center', collapse = TRUE}
# Example based on https://www.r-graph-gallery.com/137-spring-shapes-data-art/ 

# (1) Create data: ---- 
ngroup <- 50
names <- paste("G_", seq(1, ngroup), sep = "")
df <- data.frame()

set.seed(3)
for(i in seq(1:30)){
    data = data.frame(matrix(0, ngroup, 3))
    data[, 1] = i
    data[, 2] = sample(names, nrow(data))
    data[, 3] = prop.table(sample( c(rep(0, 100), c(1:ngroup)), nrow(data)))
    df = rbind(df, data)}
colnames(df) <- c("X","group","Y")
df <- df[order(df$X, df$group) , ]

# (1) Choose colors: ---- 

# (a) using RColorBrewer: 
# library(RColorBrewer)
# cur_col <- brewer.pal(11, "Paired") 
# cur_col <- colorRampPalette(cur_col)(ngroup)
# cur_col <- cur_col[sample(c(1:length(cur_col)), size = length(cur_col))]  # randomize

# (b) using unikn:
library(unikn)
cur_col <- usecol(pal = pal_unikn, n = ngroup)
# cur_col <- cur_col[sample(c(1:length(cur_col)), size = length(cur_col))]  # randomize

# (3) Use ggplot2: ---- 

library(ggplot2)

ggplot(df, aes(x = X, y = Y, fill = group)) + 
  geom_area(alpha = 1, color = Grau, size = .01 ) +
  scale_fill_manual(values = cur_col) +
  theme_void() +
  theme(legend.position = "none")
```

<img src = "./../inst/pix/README-use_pal_ggplot2-1.png" align = "center" alt = "pal_unikn" style = "border:10;"/>

## Generalization to other institutions 

The color scales included in the **unikn** package are based on the CD manual of the [University of Konstanz](https://uni-konstanz.de), Germany. 
However, the functionality provided by the package makes it easy and straightforward to define and use your own color schemes. 
Here are some examples from other institutions to illustrate how this can be achieved.  

```{r Cardiff, echo = FALSE, eval = FALSE, fig.align = 'center', fig.width = 5, fig.height = 3}
# Cardiff University, UK: 
# ToDo. 
```

#### A. [University of Freiburg](https://www.uni-freiburg.de/), Germany: 
<img src = "../inst/pix/logo_freiburg.png" align = "right" width = "120px" alt = "Uni Freiburg" style = "border:10;"/> 

The [Albert-Ludwigs Universität Freiburg](https://www.uni-freiburg.de/) provides fairly extensive information on its corporate color scheme (available [here](https://www.zuv.uni-freiburg.de/service/cd/cd-manual/farbwelt) and [here](https://www.zuv.uni-freiburg.de/service/wsg/webstyleguide/farben)). 
Colors can be defined in a variety of ways, but R comes with convenient tools (like `col2rgb` and `convertColor` in **grDevices**) to handle most cases. The most straightforward way of creating a new color palette in R is by using its HEX/HTML code (provided in character format). 
As the [University of Freiburg](https://www.uni-freiburg.de/) kindly provides their colors in this format, we can easily define the corresponding color palettes as named vectors: 

```{r Freiburg, fig.width = 7, fig.asp = .618, fig.align = 'center', fig.show = "hold", collapse = TRUE}
# Basic colors: https://www.zuv.uni-freiburg.de/service/cd/cd-manual/farbwelt

pal_freiburg_bluered <- c("#004a99", "#c1002a")
names(pal_freiburg_bluered) <- c("uni-blau", "uni-rot")

pal_freiburg_basic <- c("#004a99", "white", "#c1002a")  # add "white" for better gradients
names(pal_freiburg_basic) <- c("uni-blau", "weiss", "uni-rot")

# Web colors: https://www.zuv.uni-freiburg.de/service/wsg/webstyleguide/farben  

pal_freiburg_blue <- c("#004a99", "#2a6ebb", "#6f9ad3")
names(pal_freiburg_blue) <- c("blue-1", "blue-2", "blue-3")

pal_freiburg_grey <- c("#f2f3f1", "#e0e1dd", "#d5d6d2", "#c9cac8", 
                       "#b2b4b3", "#9a9b9c", "#747678", "#363534")
names(pal_freiburg_grey) <- c("grey-0", "grey-1", "grey-2", "grey-3", 
                              "grey-5", "grey-7", "grey-9", "grey-font")

pal_freiburg_info <- c("#2a6ebb", "#a7c1e3", "#7b2927", "#de3831", "#739600", "#92d400", 
                       "#4d4f53", "#747678", "#b2b4b3", "#d5d6d2", "#e98300", "#efbd47")
names(pal_freiburg_info) <- c("mid-blau", "hell-blau", "dark-red", "hell-red", "mid-green", "hell-green", 
                              "anthrazit", "dark-grey", "mid-grey", "hell-grey", "orange", "gelb")
```

Once a new color palette has been defined (and is available in your current R environment), we can use the `seecol()` and `usecol()` functions to view, modify, and use the palette: 

```{r seecol_freiburg, fig.width = 7, fig.asp = .618, fig.align = 'center', collapse = TRUE}
seecol(pal_freiburg_info)            # view color palette
# seecol(pal_freiburg_basic, n = 7)  # extend color palette
# seecol(c(pal_freiburg_blue, "white", pal_freiburg_grey))  # mix color palette
```

#### B. [Princeton University](https://princeton.edu/), USA: 
<img src = "../inst/pix/logo_princeton.jpg" align = "right" width = "180px" alt = "Princeton University" style = "border:10;"/>

The color scheme of [Princeton University](https://princeton.edu/) is easily recognized by its combination of orange with black and white elements. The official guidelines (available [here](https://communications.princeton.edu/guides-tools/logo-graphic-identity)) define "Princeton Orange" as Pantone (PMS) 158&nbsp;C. 

- The PANTONE&trade; color finder at <https://www.pantone.com/color-finder/158-C> yields the following color values:

    - RGB: `232 119 34`  
    - HEX/HTML: `#E87722`  
    - CMYK: `0 62 95 0`  

- However, the guide also specifies and distinguishes between 2 additional versions of orange and provides the following HEX/HTML values for them:  

    - Orange on white: "#E77500"  
    - Orange on black: "#F58025"  

These definitions suggest defining 3 separate versions of orange and corresponding color palettes: 

```{r Princeton, fig.width = 6, fig.asp = .618, fig.align = 'center', fig.show = "hold", collapse = TRUE}
# HEX values for 3 shades of orange: 
orange_basic <- "#E87722"  # Pantone 158 C
orange_white <- "#E77500"  # orange on white
orange_black <- "#F58025"  # orange on black

# Defining color palettes:
pal_princeton <- c(orange_basic, "black")
names(pal_princeton) <- c("orange", "black")

pal_princeton_1 <- c(orange_white, "white", "black")
names(pal_princeton_1) <- c("orange_w", "white", "black")

pal_princeton_2 <- c(pal = c(orange_black, "black", "white"))
names(pal_princeton_2) <- c("orange_b", "black", "white")

seecol(pal_princeton_1)  # view color palette
```

#### C. [Max Planck Society](https://www.mpg.de/), Germany: 
<img src = "../inst/pix/logo_MPG.png" align = "right" alt = "MPG" width = "150px" style = "border:10;"/>

The CD manual (available [here](https://docplayer.org/2328711-Max-planck-institut-das-erscheinungsbild-der-max-planck-gesellschaft-4-ueberarbeitete-auflage.html)) of the [Max Planck Society](https://www.mpg.de/) specifies the use of 2&nbsp;primary colors: 

- Green as Pantone 328: Using the PANTONE&trade; color finder at <https://www.pantone.com/color-finder/328-C> yields the following color values:

    - RGB: `0 115 103`    
    - HEX/HTML: `#007367`   
    - CMYK: `100 10 61 38`  

- Grey as Pantone 427: Using the PANTONE&trade; color finder at <https://www.pantone.com/color-finder/427-C> yields the following color values: 

    - RGB: `208 211 212`  
    - HEX/HTML: `#D0D3D4`   
    - CMYK: `7 3 5 8`   

```{r MPG_rgb, echo = FALSE, eval = FALSE, fig.width = 6, fig.asp = .618, fig.align = 'center', collapse = TRUE}
# Using RGB values: 
pal_mpg <- data.frame(# named colors: 
  "mpg_green" = rgb( 17, 102,  86, maxColorValue = 255),
  "mpg_gray"  = rgb(221, 222, 214, maxColorValue = 255),
  "mpg_grey"  = rgb(208, 211, 212, maxColorValue = 255)
  )
seecol(pal = list(pal_mpg))  # Ooops...
```

```{r MPG_hex, echo = FALSE, eval = FALSE, out.width = "67%", fig.asp = .75, fig.align = 'center', collapse = TRUE}
# Using HEX values:
mpg_green <- "#007367"
mpg_grey  <- "#D0D3D4"

# col2rgb(mpg_green)
# col2rgb(mpg_grey)

pal_mpg <- usecol(pal = c(mpg_green, "white", mpg_grey))
```

Again, the easiest way of defining a corresponding color palette is by creating a named vector. 
To allow for better color gradients, we insert the color `"white"` between the 2&nbsp;dedicated colors: 

```{r MPG_pal_def, fig.width = 6, fig.asp = .618, fig.align = 'center', collapse = TRUE}
pal_mpg <- c("#007367", "white", "#D0D3D4")
names(pal_mpg) <- c("mpg green", "white", "mpg grey")
```

As before, can now use the `seecol()` and `usecol()` functions to view, modify, and use the new `pal_mpg` color palette: 

```{r MPG_seecol, fig.width = 6, fig.asp = .618, fig.align = 'center', collapse = TRUE}
seecol(pal_mpg)
```


## All unikn 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>

<!-- Index of vignettes: -->

| Nr.  | Vignette | Content    |        
| ---: |:---------|:-----------|
| 1. | [Colors](colors.html) | Colors and color palettes | 
| 2. | [Text](text.html)     | Text boxes and decorations | 

<!-- eof. -->