---
title: "Customized Color Palettes & Themes"
date: 'Compiled: `r format(Sys.Date(), "%B %d, %Y")`'
output: rmarkdown::html_vignette
theme: united
df_print: kable
vignette: >
  %\VignetteIndexEntry{Customized Color Palettes & Themes}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---
***

<style>
p.caption {
  font-size: 0.9em;
}
</style>
 
```{r setup, include=FALSE}
all_times <- list()  # store the time for each chunk
knitr::knit_hooks$set(time_it = local({
  now <- NULL
  function(before, options) {
    if (before) {
      now <<- Sys.time()
    } else {
      res <- difftime(Sys.time(), now, units = "secs")
      all_times[[options$label]] <<- res
    }
  }
}))
knitr::opts_chunk$set(
  tidy = TRUE,
  tidy.opts = list(width.cutoff = 95),
  message = FALSE,
  warning = FALSE,
  time_it = TRUE
)
```

## Choosing Color Palettes and Themes
While the default Seurat and ggplot2 plots work well they can often be enhanced by customizing color palettes and themeing options used.  To simplify/streamline this process for end users scCustomize:  

**1. Sets default discrete and continuous variables that are consistent across the package and are customized to plotting conditions.**  
**2. Contains a number of shortcuts or helper functions for quick access to color palettes and themes that are frequently used.**  

```{r init}
# Load Packages
library(ggplot2)
library(dplyr)
library(magrittr)
library(patchwork)
library(scCustomize)
library(qs)

# Load Marsh et al., 2022 datasets
marsh_mouse_micro <- qread(file = "assets/marsh_2020_micro.qs")

# Load PBMC example dataset
pbmc <- pbmc3k.SeuratData::pbmc3k.final
```


```{r include=FALSE}
pbmc <- UpdateSeuratObject(pbmc)

#marsh_mouse_micro <- UpdateSeuratObject(object = marsh_mouse_micro)
```

```{r include=FALSE}
p1 <- FeaturePlot(object = pbmc, features = "CD3E", order = T)
p2 <- FeaturePlot_scCustom(seurat_object = pbmc, features = "CD3E")
p3 <- FeaturePlot_scCustom(seurat_object = pbmc, features = "MS4A1")
p4 <- FeaturePlot_scCustom(seurat_object = pbmc, features = "GZMB")
```

## Package Default Palettes  
### Plotting Continuous Variables  
The continuous palettes from the [viridis package](https://sjmgarnier.github.io/viridis/) improve plot readability and are more colorblind friendly than some commonly used continuous palettes.  When plotting continuous variables (e.g., gene expression) scCustomize uses the reverse "plasma" palette by default.  

```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = paletteer::paletteer_c(palette = "viridis::plasma", n = 250, direction = -1)) + ggtitle("Viridis Plasma Palette (reversed).")
```

```{r echo=FALSE, fig.align='center', fig.cap="*These palettes provided better contrast for continuous palettes.\n In scCustomize the default is `viridis_plasma_dark_high`*", fig.dim=c(10, 7.5)}
wrap_plots(p1, p2, p3, p4, ncol = 2) + plot_annotation(tag_levels = 'A')
```

There is one exception to this in that `Plot_Density_Custom()` and `Plot_Density_Joint()` use the "magma" palette by default.  This choice was made as I believe that the magma palette provides better color scale for these plots.

```{r echo=FALSE, fig.height=5, fig.width=13, fig.cap="*Example comparing **A.** default `Plot_Density_Custom` which uses 'magma' palette vs. **B.** plot using the 'plasma' palette.*", fig.align='center'}
# Create Plots
p1 <- Plot_Density_Custom(seurat_object = marsh_mouse_micro, features = "Fos")
p2 <- Plot_Density_Custom(seurat_object = marsh_mouse_micro, features = "Fos", viridis_palette = "plasma")
wrap_plots(p1, p2, ncol = 2) + plot_annotation(tag_levels = "A")
```

### Plotting Discrete Variables
To provide better visualizations using default parameters scCustomize sets a series of defaults for plots with discrete palettes using `scCustomize_Palette()` function.

* If only **one identity** is being plotted will use: "dodgerblue".
* If only *two identities* are being plotted will use: `NavyAndOrange()`
* If between 2 and 8 identities are being plotted will use `ColorBlind_Pal`.
* If greater than 2 identities but less than or equal to 36 will use: `DiscretePalette_scCustomize(num_colors = 36, palette = "polychrome")`
* If greater than 36 identities will use dynamic varibow palette: `DiscretePalette_scCustomize(num_colors = *Number of identities*, palette = "varibow", shuffle_pal = TRUE)`

```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = "dodgerblue", label_color_num = FALSE) + ggtitle("'dodgerblue' (1 color)")
PalettePlot(pal = NavyAndOrange(), label_color_num = FALSE) + ggtitle("NavyAndOrange() (2 colors)")
PalettePlot(pal = ColorBlind_Pal(), label_color_num = FALSE) + ggtitle("ColorBlind_Pal() (8 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 36, palette = "polychrome"), label_color_num = FALSE) + ggtitle("polychrome (36 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 50, palette = "varibow", shuffle_pal = TRUE), label_color_num = FALSE) + ggtitle("varibow (50 color version)")
```

## Helper Functions & Shortcuts  

## Continuous Palettes
scCustomize has a number of quick helpers for access to palettes from viridis package.  For more information on viridis palettes.  These can be supplied to any appropriate plotting function in scCustomize or any other plot in R.

* viridis_plasma_dark_high
* viridis_plasma_light_high
* viridis_magma_dark_high
* viridis_magma_light_high
* viridis_inferno_dark_high
* viridis_inferno_light_high
* viridis_dark_high
* viridis_light_high


```{r}
p1 <- FeaturePlot_scCustom(seurat_object = pbmc, features = "CD3E")
p2 <- FeaturePlot_scCustom(seurat_object = pbmc, colors_use = viridis_magma_dark_high, features = "CD3E")
p3 <- FeaturePlot_scCustom(seurat_object = pbmc, colors_use = viridis_inferno_dark_high, features = "CD3E")
p4 <- FeaturePlot_scCustom(seurat_object = pbmc, colors_use = viridis_light_high, features = "CD3E")
```

```{r echo=FALSE, fig.align='center', fig.cap="*These palettes provided better contrast for continuous palettes.\n In scCustomize the default is `viridis_plasma_dark_high`*", fig.dim=c(10, 7.5)}
wrap_plots(p1, p2, p3, p4, ncol = 2) + plot_annotation(tag_levels = 'A')
```


## Large Discrete Palettes
### `DiscretePalette_scCustomize()`
The function `DiscretePalette_scCustomize` is function inspired and modified from `Seurat::DiscretePalette()`.  Under the hood most of the palettes are called using [paletteer package](https://github.com/EmilHvitfeldt/paletteer) to call palettes without adding package dependencies.  The following palettes can be specified:

* alphabet (24)
* alphabet2 (24)
* glasbey (32)
* polychrome (36)
* stepped (24)
* ditto_seq (40)
* varibow (Dynamic)

### Palettes can either be saved to global environment as variable or called directly within other functions:
```{r eval=FALSE}
# Save as variable to global environment
polychrome_pal <- DiscretePalette_scCustomize(num_colors = 36, palette = "polychrome")

# Call within another function
DimPlot_scCustom(seurat_object = obj_name, colors_use = DiscretePalette_scCustomize(num_colors = 26, palette = "polychrome"))
```

### The "polychrome" palette is the new default for plots with <36 levels and "varibow" when more than 36 levels
```{r fig.align='center'}
DimPlot_scCustom(seurat_object = pbmc)
```


### Visualize Palettes
To visualize these or any other palette you can use the `PalettePlot()` function.
```{r eval=FALSE}
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 26, palette = "alphabet"))

PalettePlot(pal = c("color1", "color2", ...)

```

```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 26, palette = "alphabet")) + ggtitle("alphabet (26 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 26, palette = "alphabet2")) + ggtitle("alphabet2 (26 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 32, palette = "glasbey")) + ggtitle("glasbey (32 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 36, palette = "polychrome")) + ggtitle("polychrome (36 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 24, palette = "stepped")) + ggtitle("stepped (24 colors")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 40, palette = "ditto_seq")) + ggtitle("ditto_seq (40 colors)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 50, palette = "varibow")) + ggtitle("varibow (50 color version)")
```

### Dynamic Palettes
Among the discrete palettes provide the "varibow" palette is actually a dynamic palette whose colors will adjust across the rainbow according to `num_colors` provided:
```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 10, palette = "varibow")) + ggtitle("varibow (10 color version)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 20, palette = "varibow")) + ggtitle("varibow (20 color version)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 30, palette = "varibow")) + ggtitle("varibow (30 color version)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 40, palette = "varibow")) + ggtitle("varibow (40 color version)")
```

### Shuffle Palettes
Sometimes it can be helpful to use different order for the discrete palettes depending on the end plot generated (This can be especially true with "varibow" sometimes).  `DiscretePalette_scCustomize` has optional parameter that will randomly shuffle the returned palette (see `shuffle_pal` and `seed` parameter to allow for reproducible shuffling.)
```{r eval=FALSE}
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 30, palette = "varibow")) + ggtitle("varibow (normal)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 30, palette = "varibow"), shuffle_pal = TRUE) + ggtitle("varibow (shuffled)")
```

```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 30, palette = "varibow")) + ggtitle("varibow (normal)")
PalettePlot(pal = DiscretePalette_scCustomize(num_colors = 30, palette = "varibow", shuffle_pal = TRUE)) + ggtitle("varibow (shuffled)")
```


## Small Discrete Palettes
Finally scCustomize contains shortcuts for some shorter discrete palettes that can be useful for plotting groups, treatments, genotypes, etc.
```{r echo=FALSE, fig.height=1,fig.width=11}
PalettePlot(pal = NavyAndOrange()) + ggtitle("NavyAndOrange(): 2 color palette.")
PalettePlot(pal = JCO_Four()) + ggtitle("JCO_Four(): 4 color palette from ggsci package.")
PalettePlot(pal = Dark2_Pal()) + ggtitle("Dark2_Pal(): 8 color Dark2 palette from RColorBrewer package")
PalettePlot(pal = ColorBlind_Pal()) + ggtitle("ColorBlind_Pal(): 8 color modified color blind safe palette")
```


## Themes & Plot Helpers
ggplot2 themeing works absolutely great but can also be simplified by wrapping commonly used post-plot themes into less verbose functions.
  
scCustomize contains a few customized themes and ggplot2 helpers that simplify post plot themeing/alterations.  
*NOTE: These functions can be used with any ggplot2 plot and are not limited to modifying scCustomize plots.*  

* `UnRotate_X()` Undo x-axis label rotation
* `Move_Legend()` Select new location to move legend
* `Blank_Theme()` Removes all axis labels and axes from plot
* `theme_ggprism_mod()` Modified version of `ggprism::theme_prism()`


## Suggestions/Enhancements?
If you have any ideas for additional color palettes that would be helpful to add or ggplot2 themeing functions please post as [Pull Request](https://github.com/samuel-marsh/scCustomize/pulls) on GitHub!
