├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ ├── pkgdown.yaml │ └── test-coverage.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── NEWS.md ├── R ├── ggokabeito-package.R ├── palette.R └── scales.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── ggokabeito.Rproj ├── inst └── WORDLIST ├── man ├── figures │ ├── README-pressure-1.png │ ├── README-unnamed-chunk-2-1.png │ ├── README-unnamed-chunk-2-2.png │ ├── README-unnamed-chunk-2-3.png │ └── README-unnamed-chunk-3-1.png ├── ggokabeito-package.Rd ├── palette_okabe_ito.Rd └── scale_okabe_ito.Rd └── tests ├── spelling.R ├── testthat.R └── testthat ├── _snaps └── scales │ ├── edge-color.svg │ ├── scale-color-with-alpha-and-name.svg │ ├── scale-color.svg │ └── scale-f-c-color-alpha-joint-name.svg ├── helper-vdiffr.R ├── test-palette.R └── test-scales.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^ggokabeito\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^README\.Rmd$ 5 | ^\.github$ 6 | ^_pkgdown\.yml$ 7 | ^docs$ 8 | ^pkgdown$ 9 | ^codecov\.yml$ 10 | ^CODE_OF_CONDUCT\.md$ 11 | ^cran-comments\.md$ 12 | ^rhub\.R$ 13 | ^CRAN-RELEASE$ 14 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macOS-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | R_COMPILE_AND_INSTALL_PACKAGES: never 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | 35 | - uses: r-lib/actions/setup-pandoc@v1 36 | 37 | - uses: r-lib/actions/setup-r@v1 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - name: Install remotes package 44 | run: install.packages('remotes') 45 | shell: Rscript {0} 46 | 47 | - name: Install igraph binary 48 | if: runner.os != 'Linux' 49 | run: install.packages('igraph', type = 'binary') 50 | shell: Rscript {0} 51 | 52 | - name: Install system dependencies (Linux) 53 | if: runner.os == 'Linux' 54 | run: | 55 | while read -r cmd 56 | do 57 | eval sudo $cmd 58 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') 59 | 60 | - uses: r-lib/actions/setup-r-dependencies@v1 61 | with: 62 | extra-packages: rcmdcheck 63 | 64 | - uses: r-lib/actions/check-r-package@v1 65 | 66 | - name: Show testthat output 67 | if: always() 68 | run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true 69 | shell: bash 70 | 71 | - name: Upload check results 72 | if: failure() 73 | uses: actions/upload-artifact@main 74 | with: 75 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 76 | path: check 77 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | tags: ['*'] 7 | 8 | name: pkgdown 9 | 10 | jobs: 11 | pkgdown: 12 | runs-on: ubuntu-latest 13 | env: 14 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - uses: r-lib/actions/setup-pandoc@v1 19 | 20 | - uses: r-lib/actions/setup-r@v1 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v1 25 | with: 26 | extra-packages: pkgdown 27 | needs: website 28 | 29 | - name: Deploy package 30 | run: | 31 | git config --local user.name "$GITHUB_ACTOR" 32 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 33 | Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' 34 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-r@v1 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v1 25 | with: 26 | extra-packages: covr 27 | 28 | - name: Test coverage 29 | run: covr::codecov() 30 | shell: Rscript {0} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | docs 7 | R/rhub.R 8 | rhub.R 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards 42 | of acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies 54 | when an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail 56 | address, posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at malcolmbarrett@gmail.com. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.0, 118 | available at . 119 | 120 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 121 | enforcement ladder](https://github.com/mozilla/diversity). 122 | 123 | [homepage]: https://www.contributor-covenant.org 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | . Translations are available at . 127 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggokabeito 2 | Title: 'Okabe-Ito' Scales for 'ggplot2' and 'ggraph' 3 | Version: 0.1.0.9000 4 | Authors@R: 5 | person("Malcolm", "Barrett", , "malcolmbarrett@gmail.com", role = c("aut", "cre"), 6 | comment = c(ORCID = "0000-0003-0299-5825")) 7 | Description: Discrete scales for the colorblind-friendly 'Okabe-Ito' 8 | palette, including 'color', 'fill', and 'edge_colour'. 'ggokabeito' 9 | provides 'ggplot2' and 'ggraph' scales to easily use the 'Okabe-Ito' 10 | palette in your data visualizations. 11 | License: MIT + file LICENSE 12 | URL: https://github.com/malcolmbarrett/ggokabeito, 13 | https://malcolmbarrett.github.io/ggokabeito/ 14 | BugReports: https://github.com/malcolmbarrett/ggokabeito/issues 15 | Depends: 16 | R (>= 4.0.0) 17 | Imports: 18 | ggplot2, 19 | grDevices 20 | Suggests: 21 | covr, 22 | ggraph, 23 | igraph, 24 | spelling, 25 | testthat (>= 3.0.0), 26 | vdiffr 27 | Config/testthat/edition: 3 28 | Encoding: UTF-8 29 | Language: en-US 30 | Roxygen: list(markdown = TRUE) 31 | RoxygenNote: 7.1.2 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2021 2 | COPYRIGHT HOLDER: ggokabeito authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2021 ggokabeito authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(palette_okabe_ito) 4 | export(scale_color_okabe_ito) 5 | export(scale_colour_okabe_ito) 6 | export(scale_edge_color_okabe_ito) 7 | export(scale_edge_colour_okabe_ito) 8 | export(scale_fill_okabe_ito) 9 | export(scale_okabe_ito) 10 | importFrom(grDevices,palette.colors) 11 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # ggokabeito 0.1.0.9000 2 | 3 | * Allowed `palette_okabe_ito()` to specify color names in the `order` argument (#3) 4 | * Added a `NEWS.md` file to track changes to the package. 5 | -------------------------------------------------------------------------------- /R/ggokabeito-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | ## usethis namespace: start 5 | #' @importFrom grDevices palette.colors 6 | ## usethis namespace: end 7 | NULL 8 | -------------------------------------------------------------------------------- /R/palette.R: -------------------------------------------------------------------------------- 1 | #' Okabe-Ito Palette 2 | #' 3 | #' `palette_okabe_ito()` is a wrapper around `palette.colors()` that returns the 4 | #' Okabe-Ito palette in R 4.0.0 or greater. `palette_okabe_ito()` returns an 5 | #' unnamed vector of colors for better use with ggplot2. Additionally, black is 6 | #' the last color returned by `palette_okabe_ito()` when 9 colors are needed 7 | #' instead of the first, as in `palette.colors()`. 8 | #' 9 | #' @param order A numeric vector, the order of the colors, or a character vector 10 | #' of color names, of: "black", "orange", "skyblue", "bluishgreen", "yellow", 11 | #' "blue", "vermillion", "reddishpurple", "gray". If `alpha` is not `NULL`, 12 | #' you must use an integer vector since the colors are not returned with 13 | #' names. 14 | #' @inheritParams grDevices::palette.colors 15 | #' 16 | #' @return A character vector of hex codes 17 | #' @export 18 | #' 19 | #' @examples 20 | #' 21 | #' palette_okabe_ito() 22 | #' 23 | #' palette_okabe_ito(order = c(2, 3, 5), alpha = 0.9) 24 | #' 25 | #' palette_okabe_ito(order = c("bluishgreen", "yellow", "blue")) 26 | palette_okabe_ito <- function(order = 1:9, alpha = NULL, recycle = FALSE) { 27 | check_order(order, alpha) 28 | if (!is.null(alpha)) { 29 | stopifnot(is.numeric(alpha), alpha >= 0, alpha <= 1) 30 | } 31 | stopifnot(is.logical(recycle)) 32 | 33 | palette_colors( 34 | palette = "Okabe-Ito", 35 | alpha = alpha, 36 | recycle = recycle, 37 | order = order 38 | ) 39 | } 40 | 41 | check_order <- function(order, alpha) { 42 | if (is.numeric(order) && all(order > 0)) { 43 | return(invisible()) 44 | } else if (is.character(order) && all(order %in% color_names())) { 45 | if (!is.null(alpha)) { 46 | stop( 47 | "Cannot use color names for `order` when specifying `alpha`", 48 | call. = FALSE 49 | ) 50 | } 51 | return(invisible()) 52 | } else { 53 | stop( 54 | "`order` must be an integer vector (1-9) or ", 55 | "a character vector of color names (of: ", 56 | paste(color_names(), collapse = ", "), 57 | ")", 58 | call. = FALSE 59 | ) 60 | } 61 | } 62 | 63 | palette_colors <- function(..., order = 1:9) { 64 | unname(palette.colors(n = 9, ...)[c(2:9, 1)][order]) 65 | } 66 | 67 | color_names <- function() { 68 | names(palette.colors(n = 9)) 69 | } 70 | -------------------------------------------------------------------------------- /R/scales.R: -------------------------------------------------------------------------------- 1 | #' Okabe-Ito Scales for ggplot2 and ggraph 2 | #' 3 | #' Discrete scales for the colorblind-friendly Okabe-Ito palette, including 4 | #' `color`, `fill`, and `edge_colour`. See [palette_okabe_ito] for 5 | #' details. 6 | #' 7 | #' @inheritParams ggplot2::discrete_scale 8 | #' @inheritParams palette_okabe_ito 9 | #' @inheritParams grDevices::palette.colors 10 | #' @param ... Additional arguments passed to [ggplot2::discrete_scale()] 11 | #' 12 | #' @return A ggplot or ggraph scale 13 | #' @export 14 | #' 15 | #' @examples 16 | #' library(ggplot2) 17 | #' 18 | #' ggplot(mpg, aes(cty, hwy, color = class)) + 19 | #' geom_point() + 20 | #' scale_color_okabe_ito() 21 | #' 22 | #' ggplot(mpg, aes(cty, hwy, color = factor(cyl))) + 23 | #' geom_point(alpha = 0.7) + 24 | #' scale_color_okabe_ito(name = "Cylinders", alpha = .9) 25 | #' 26 | #' ggplot(mpg, aes(hwy, color = class, fill = class)) + 27 | #' geom_density() + 28 | #' scale_fill_okabe_ito(name = "Class", alpha = .9) + 29 | #' scale_color_okabe_ito(name = "Class") 30 | scale_okabe_ito <- function(aesthetics, order = 1:9, alpha = 1, ...) { 31 | values <- palette_okabe_ito(order = order, alpha = alpha, recycle = FALSE) 32 | pal <- function(n) { 33 | if (n > length(values)) { 34 | msg <- paste( 35 | "Insufficient values in manual scale.", n, "needed but only", 36 | length(values), "provided." 37 | ) 38 | stop(msg, call. = FALSE) 39 | } 40 | 41 | values 42 | } 43 | 44 | ggplot2::discrete_scale( 45 | aesthetics = aesthetics, 46 | scale_name = "manual", 47 | palette = pal, 48 | ... 49 | ) 50 | } 51 | 52 | #' @rdname scale_okabe_ito 53 | #' @export 54 | scale_colour_okabe_ito <- function(aesthetics = "colour", order = 1:9, alpha = NULL, ...) { 55 | scale_okabe_ito( 56 | aesthetics = aesthetics, 57 | order = order, 58 | alpha = alpha, 59 | ... 60 | ) 61 | } 62 | 63 | #' @rdname scale_okabe_ito 64 | #' @export 65 | scale_color_okabe_ito <- scale_colour_okabe_ito 66 | 67 | #' @rdname scale_okabe_ito 68 | #' @export 69 | scale_fill_okabe_ito <- function(aesthetics = "fill", order = 1:9, alpha = NULL, ...) { 70 | scale_okabe_ito( 71 | aesthetics = aesthetics, 72 | order = order, 73 | alpha = alpha, 74 | ... 75 | ) 76 | } 77 | 78 | #' @export 79 | #' @name scale_okabe_ito 80 | scale_edge_colour_okabe_ito <- function(aesthetics = "edge_colour", order = 1:9, alpha = NULL, ...) { 81 | scale_okabe_ito( 82 | aesthetics = aesthetics, 83 | order = order, 84 | alpha = alpha, 85 | ... 86 | ) 87 | } 88 | 89 | #' @export 90 | #' @name scale_okabe_ito 91 | scale_edge_color_okabe_ito <- scale_edge_colour_okabe_ito 92 | 93 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "80%", 13 | dpi = 320, 14 | out.width = "80%", 15 | fig.width = 6, 16 | fig.asp = 0.618, 17 | fig.retina = 2, 18 | fig.align = "center" 19 | ) 20 | ``` 21 | 22 | # ggokabeito 23 | 24 | 25 | [![R-CMD-check](https://github.com/malcolmbarrett/ggokabeito/workflows/R-CMD-check/badge.svg)](https://github.com/malcolmbarrett/ggokabeito/actions) 26 | [![Codecov test coverage](https://codecov.io/gh/malcolmbarrett/ggokabeito/branch/main/graph/badge.svg)](https://app.codecov.io/gh/malcolmbarrett/ggokabeito?branch=main) 27 | [![CRAN status](https://www.r-pkg.org/badges/version/ggokabeito)](https://CRAN.R-project.org/package=ggokabeito) 28 | [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) 29 | 30 | 31 | ggokabeito provides ggplot2 and ggraph scales to easily use the discrete, colorblind-friendly 'Okabe-Ito' palette in your data visualizations. Currently, ggokabeito provides the following scales: 32 | 33 | * `scale_color_okabe_ito()`/`scale_colour_okabe_ito()` 34 | * `scale_fill_okabe_ito()` 35 | * `scale_edge_color_okabe_ito()`/`scale_edge_colour_okabe_ito()` 36 | 37 | ## Installation 38 | 39 | You can install ggokabeito from CRAN with: 40 | 41 | ``` r 42 | install.packages("ggokabeito") 43 | ``` 44 | 45 | You can alternatively install the development version of ggokabeito from [GitHub](https://github.com/) with: 46 | 47 | ``` r 48 | # install.packages("devtools") 49 | devtools::install_github("malcolmbarrett/ggokabeito") 50 | ``` 51 | 52 | ## Examples 53 | 54 | ```{r} 55 | library(ggokabeito) 56 | library(ggplot2) 57 | 58 | ggplot(mpg, aes(cty, hwy, color = class)) + 59 | geom_point() + 60 | scale_color_okabe_ito() 61 | 62 | ggplot(mpg, aes(cty, hwy, color = factor(cyl))) + 63 | geom_point(alpha = 0.7) + 64 | scale_color_okabe_ito(name = "Cylinders", alpha = .9) 65 | 66 | ggplot(mpg, aes(hwy, color = class, fill = class)) + 67 | geom_density() + 68 | scale_fill_okabe_ito(name = "Class", alpha = .9) + 69 | scale_color_okabe_ito(name = "Class") 70 | ``` 71 | 72 | ggokabeito also works with ggraph 73 | 74 | ```{r} 75 | # example from https://www.data-imaginist.com/2017/ggraph-introduction-edges/ 76 | library(ggraph, warn.conflicts = FALSE) 77 | library(igraph, warn.conflicts = FALSE) 78 | 79 | graph <- graph_from_data_frame(highschool) 80 | pop1957 <- degree( 81 | delete_edges(graph, which(E(graph)$year == 1957)), 82 | mode = "in" 83 | ) 84 | pop1958 <- degree( 85 | delete_edges(graph, which(E(graph)$year == 1958)), 86 | mode = "in" 87 | ) 88 | V(graph)$pop_devel <- ifelse( 89 | pop1957 < pop1958, 90 | "increased", 91 | ifelse(pop1957 > pop1958, "decreased", 92 | "unchanged" 93 | ) 94 | ) 95 | 96 | V(graph)$popularity <- pmax(pop1957, pop1958) 97 | E(graph)$year <- as.character(E(graph)$year) 98 | 99 | ggraph(graph, layout = "kk") + 100 | geom_edge_link(aes(colour = as.character(year))) + 101 | scale_edge_color_okabe_ito() 102 | ``` 103 | 104 | 105 | 106 | ## Similar work 107 | 108 | ggokabeito is heavily inspired by the excellent [colorblindr](https://github.com/clauswilke/colorblindr) package. However, colorblindr is not currently on CRAN and includes some complex features for analyzing colorblind safeness that are not necessary for using the Okabe-Ito palette. Additionally, colorblindr was developed prior to R 4.0.0, which set Okabe-Ito as the default discrete color palette. ggokabeito thus has fewer overall dependencies but a strong one on R 4.0.0 or greater. 109 | 110 | ## Code of Conduct 111 | 112 | Please note that the ggokabeito project is released with a [Contributor Code of Conduct](https://malcolmbarrett.github.io/ggokabeito/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # ggokabeito 5 | 6 | 7 | 8 | [![R-CMD-check](https://github.com/malcolmbarrett/ggokabeito/workflows/R-CMD-check/badge.svg)](https://github.com/malcolmbarrett/ggokabeito/actions) 9 | [![Codecov test 10 | coverage](https://codecov.io/gh/malcolmbarrett/ggokabeito/branch/main/graph/badge.svg)](https://app.codecov.io/gh/malcolmbarrett/ggokabeito?branch=main) 11 | [![CRAN 12 | status](https://www.r-pkg.org/badges/version/ggokabeito)](https://CRAN.R-project.org/package=ggokabeito) 13 | [![Lifecycle: 14 | experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) 15 | 16 | 17 | ggokabeito provides ggplot2 and ggraph scales to easily use the 18 | discrete, colorblind-friendly ‘Okabe-Ito’ palette in your data 19 | visualizations. Currently, ggokabeito provides the following scales: 20 | 21 | - `scale_color_okabe_ito()`/`scale_colour_okabe_ito()` 22 | - `scale_fill_okabe_ito()` 23 | - `scale_edge_color_okabe_ito()`/`scale_edge_colour_okabe_ito()` 24 | 25 | ## Installation 26 | 27 | You can install ggokabeito from CRAN with: 28 | 29 | ``` r 30 | install.packages("ggokabeito") 31 | ``` 32 | 33 | You can alternatively install the development version of ggokabeito from 34 | [GitHub](https://github.com/) with: 35 | 36 | ``` r 37 | # install.packages("devtools") 38 | devtools::install_github("malcolmbarrett/ggokabeito") 39 | ``` 40 | 41 | ## Examples 42 | 43 | ``` r 44 | library(ggokabeito) 45 | library(ggplot2) 46 | 47 | ggplot(mpg, aes(cty, hwy, color = class)) + 48 | geom_point() + 49 | scale_color_okabe_ito() 50 | ``` 51 | 52 | 53 | 54 | ``` r 55 | ggplot(mpg, aes(cty, hwy, color = factor(cyl))) + 56 | geom_point(alpha = 0.7) + 57 | scale_color_okabe_ito(name = "Cylinders", alpha = .9) 58 | ``` 59 | 60 | 61 | 62 | ``` r 63 | ggplot(mpg, aes(hwy, color = class, fill = class)) + 64 | geom_density() + 65 | scale_fill_okabe_ito(name = "Class", alpha = .9) + 66 | scale_color_okabe_ito(name = "Class") 67 | ``` 68 | 69 | 70 | 71 | ggokabeito also works with ggraph 72 | 73 | ``` r 74 | # example from https://www.data-imaginist.com/2017/ggraph-introduction-edges/ 75 | library(ggraph, warn.conflicts = FALSE) 76 | library(igraph, warn.conflicts = FALSE) 77 | 78 | graph <- graph_from_data_frame(highschool) 79 | pop1957 <- degree( 80 | delete_edges(graph, which(E(graph)$year == 1957)), 81 | mode = "in" 82 | ) 83 | pop1958 <- degree( 84 | delete_edges(graph, which(E(graph)$year == 1958)), 85 | mode = "in" 86 | ) 87 | V(graph)$pop_devel <- ifelse( 88 | pop1957 < pop1958, 89 | "increased", 90 | ifelse(pop1957 > pop1958, "decreased", 91 | "unchanged" 92 | ) 93 | ) 94 | 95 | V(graph)$popularity <- pmax(pop1957, pop1958) 96 | E(graph)$year <- as.character(E(graph)$year) 97 | 98 | ggraph(graph, layout = "kk") + 99 | geom_edge_link(aes(colour = as.character(year))) + 100 | scale_edge_color_okabe_ito() 101 | ``` 102 | 103 | 104 | 105 | ## Similar work 106 | 107 | ggokabeito is heavily inspired by the excellent 108 | [colorblindr](https://github.com/clauswilke/colorblindr) package. 109 | However, colorblindr is not currently on CRAN and includes some complex 110 | features for analyzing colorblind safeness that are not necessary for 111 | using the Okabe-Ito palette. Additionally, colorblindr was developed 112 | prior to R 4.0.0, which set Okabe-Ito as the default discrete color 113 | palette. ggokabeito thus has fewer overall dependencies but a strong one 114 | on R 4.0.0 or greater. 115 | 116 | ## Code of Conduct 117 | 118 | Please note that the ggokabeito project is released with a [Contributor 119 | Code of 120 | Conduct](https://malcolmbarrett.github.io/ggokabeito/CODE_OF_CONDUCT.html). 121 | By contributing to this project, you agree to abide by its terms. 122 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://malcolmbarrett.github.io/ggokabeito 2 | 3 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /ggokabeito.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | Additonal 2 | ORCID 3 | Okabe 4 | colour 5 | ggplot 6 | ggraph 7 | github 8 | https 9 | -------------------------------------------------------------------------------- /man/figures/README-pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcolmbarrett/ggokabeito/e28e8b7a0a3301ac40722fb07ed082bde424bb8f/man/figures/README-pressure-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcolmbarrett/ggokabeito/e28e8b7a0a3301ac40722fb07ed082bde424bb8f/man/figures/README-unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcolmbarrett/ggokabeito/e28e8b7a0a3301ac40722fb07ed082bde424bb8f/man/figures/README-unnamed-chunk-2-2.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-2-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcolmbarrett/ggokabeito/e28e8b7a0a3301ac40722fb07ed082bde424bb8f/man/figures/README-unnamed-chunk-2-3.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcolmbarrett/ggokabeito/e28e8b7a0a3301ac40722fb07ed082bde424bb8f/man/figures/README-unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /man/ggokabeito-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggokabeito-package.R 3 | \docType{package} 4 | \name{ggokabeito-package} 5 | \alias{ggokabeito} 6 | \alias{ggokabeito-package} 7 | \title{ggokabeito: 'Okabe-Ito' Scales for 'ggplot2' and 'ggraph'} 8 | \description{ 9 | Discrete scales for the colorblind-friendly 'Okabe-Ito' palette, including 'color', 'fill', and 'edge_colour'. 'ggokabeito' provides 'ggplot2' and 'ggraph' scales to easily use the 'Okabe-Ito' palette in your data visualizations. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://github.com/malcolmbarrett/ggokabeito} 15 | \item \url{https://malcolmbarrett.github.io/ggokabeito/} 16 | \item Report bugs at \url{https://github.com/malcolmbarrett/ggokabeito/issues} 17 | } 18 | 19 | } 20 | \author{ 21 | \strong{Maintainer}: Malcolm Barrett \email{malcolmbarrett@gmail.com} (\href{https://orcid.org/0000-0003-0299-5825}{ORCID}) 22 | 23 | } 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/palette_okabe_ito.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/palette.R 3 | \name{palette_okabe_ito} 4 | \alias{palette_okabe_ito} 5 | \title{Okabe-Ito Palette} 6 | \usage{ 7 | palette_okabe_ito(order = 1:9, alpha = NULL, recycle = FALSE) 8 | } 9 | \arguments{ 10 | \item{order}{A numeric vector, the order of the colors, or a character vector 11 | of color names, of: "black", "orange", "skyblue", "bluishgreen", "yellow", 12 | "blue", "vermillion", "reddishpurple", "gray". If \code{alpha} is not \code{NULL}, 13 | you must use an integer vector since the colors are not returned with 14 | names.} 15 | 16 | \item{alpha}{an alpha-transparency level in the range [0,1] 17 | (0 means transparent and 1 means opaque).} 18 | 19 | \item{recycle}{logical indicating what happens in case \code{n > 20 | length(palette(.))}. By default (\code{recycle = FALSE}), the 21 | result is as for \code{n = NULL}, but with a warning.} 22 | } 23 | \value{ 24 | A character vector of hex codes 25 | } 26 | \description{ 27 | \code{palette_okabe_ito()} is a wrapper around \code{palette.colors()} that returns the 28 | Okabe-Ito palette in R 4.0.0 or greater. \code{palette_okabe_ito()} returns an 29 | unnamed vector of colors for better use with ggplot2. Additionally, black is 30 | the last color returned by \code{palette_okabe_ito()} when 9 colors are needed 31 | instead of the first, as in \code{palette.colors()}. 32 | } 33 | \examples{ 34 | 35 | palette_okabe_ito() 36 | 37 | palette_okabe_ito(order = c(2, 3, 5), alpha = 0.9) 38 | 39 | palette_okabe_ito(order = c("bluishgreen", "yellow", "blue")) 40 | } 41 | -------------------------------------------------------------------------------- /man/scale_okabe_ito.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/scales.R 3 | \name{scale_okabe_ito} 4 | \alias{scale_okabe_ito} 5 | \alias{scale_colour_okabe_ito} 6 | \alias{scale_color_okabe_ito} 7 | \alias{scale_fill_okabe_ito} 8 | \alias{scale_edge_colour_okabe_ito} 9 | \alias{scale_edge_color_okabe_ito} 10 | \title{Okabe-Ito Scales for ggplot2 and ggraph} 11 | \usage{ 12 | scale_okabe_ito(aesthetics, order = 1:9, alpha = 1, ...) 13 | 14 | scale_colour_okabe_ito(aesthetics = "colour", order = 1:9, alpha = NULL, ...) 15 | 16 | scale_color_okabe_ito(aesthetics = "colour", order = 1:9, alpha = NULL, ...) 17 | 18 | scale_fill_okabe_ito(aesthetics = "fill", order = 1:9, alpha = NULL, ...) 19 | 20 | scale_edge_colour_okabe_ito( 21 | aesthetics = "edge_colour", 22 | order = 1:9, 23 | alpha = NULL, 24 | ... 25 | ) 26 | 27 | scale_edge_color_okabe_ito( 28 | aesthetics = "edge_colour", 29 | order = 1:9, 30 | alpha = NULL, 31 | ... 32 | ) 33 | } 34 | \arguments{ 35 | \item{aesthetics}{The names of the aesthetics that this scale works with.} 36 | 37 | \item{order}{A numeric vector, the order of the colors, or a character vector 38 | of color names, of: "black", "orange", "skyblue", "bluishgreen", "yellow", 39 | "blue", "vermillion", "reddishpurple", "gray". If \code{alpha} is not \code{NULL}, 40 | you must use an integer vector since the colors are not returned with 41 | names.} 42 | 43 | \item{alpha}{an alpha-transparency level in the range [0,1] 44 | (0 means transparent and 1 means opaque).} 45 | 46 | \item{...}{Additonal arguments passed to \code{\link[ggplot2:discrete_scale]{ggplot2::discrete_scale()}}} 47 | } 48 | \value{ 49 | A ggplot or ggraph scale 50 | } 51 | \description{ 52 | Discrete scales for the colorblind-friendly Okabe-Ito palette, including 53 | \code{color}, \code{fill}, and \code{edge_colour}. See \link{palette_okabe_ito} for 54 | details. 55 | } 56 | \examples{ 57 | library(ggplot2) 58 | 59 | ggplot(mpg, aes(cty, hwy, color = class)) + 60 | geom_point() + 61 | scale_color_okabe_ito() 62 | 63 | ggplot(mpg, aes(cty, hwy, color = factor(cyl))) + 64 | geom_point(alpha = 0.7) + 65 | scale_color_okabe_ito(name = "Cylinders", alpha = .9) 66 | 67 | ggplot(mpg, aes(hwy, color = class, fill = class)) + 68 | geom_density() + 69 | scale_fill_okabe_ito(name = "Class", alpha = .9) + 70 | scale_color_okabe_ito(name = "Class") 71 | } 72 | -------------------------------------------------------------------------------- /tests/spelling.R: -------------------------------------------------------------------------------- 1 | if(requireNamespace('spelling', quietly = TRUE)) 2 | spelling::spell_check_test(vignettes = TRUE, error = FALSE, 3 | skip_on_cran = TRUE) 4 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(ggokabeito) 3 | 4 | test_check("ggokabeito") 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/scales/scale-color-with-alpha-and-name.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 20 268 | 30 269 | 40 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 10 280 | 15 281 | 20 282 | 25 283 | 30 284 | 35 285 | cty 286 | hwy 287 | 288 | Cylinders 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 4 298 | 5 299 | 6 300 | 8 301 | Scale color with alpha and name 302 | 303 | 304 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/scales/scale-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 20 268 | 30 269 | 40 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 10 280 | 15 281 | 20 282 | 25 283 | 30 284 | 35 285 | cty 286 | hwy 287 | 288 | class 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 2seater 304 | compact 305 | midsize 306 | minivan 307 | pickup 308 | subcompact 309 | suv 310 | Scale color 311 | 312 | 313 | -------------------------------------------------------------------------------- /tests/testthat/helper-vdiffr.R: -------------------------------------------------------------------------------- 1 | expect_doppelganger <- function(title, fig, ...) { 2 | testthat::skip_if_not_installed("vdiffr") 3 | vdiffr::expect_doppelganger(title, fig, ...) 4 | } 5 | -------------------------------------------------------------------------------- /tests/testthat/test-palette.R: -------------------------------------------------------------------------------- 1 | test_that("palette_colors() returns correct vector", { 2 | expect_equal( 3 | palette_colors(alpha = 1), 4 | c("#E69F00FF", "#56B4E9FF", "#009E73FF", "#F0E442FF", "#0072B2FF", 5 | "#D55E00FF", "#CC79A7FF", "#999999FF", "#000000FF") 6 | ) 7 | 8 | expect_null(names(palette_colors())) 9 | 10 | expect_length(palette_colors(), 9) 11 | }) 12 | 13 | test_that("palette_okabe_ito() returns correct vector", { 14 | expect_equal( 15 | palette_okabe_ito(order = c(2, 3, 5), alpha = 0.9), 16 | c("#56B4E9E6", "#009E73E6", "#0072B2E6") 17 | ) 18 | 19 | expect_equal( 20 | palette_okabe_ito(order = c("bluishgreen", "yellow", "blue")), 21 | c("#009E73", "#F0E442", "#0072B2") 22 | ) 23 | 24 | expect_null(names(palette_okabe_ito())) 25 | 26 | expect_length(palette_okabe_ito(), 9) 27 | expect_length(palette_okabe_ito(order = c(2, 3, 5)), 3) 28 | }) 29 | 30 | test_that("palette_okabe_ito() errors correctly", { 31 | expect_error( 32 | palette_okabe_ito(order = "bluishgreen", alpha = 1), 33 | "Cannot use color names for `order` when specifying `alpha`" 34 | ) 35 | 36 | expect_error( 37 | palette_okabe_ito(order = TRUE), 38 | "`order` must be an integer vector \\(1\\-9\\) or a character vector" 39 | ) 40 | }) 41 | -------------------------------------------------------------------------------- /tests/testthat/test-scales.R: -------------------------------------------------------------------------------- 1 | test_that("ggplot2 scales work", { 2 | library(ggplot2, warn.conflicts = FALSE) 3 | p1 <- ggplot(mpg, aes(cty, hwy, color = class)) + 4 | geom_point() + 5 | scale_color_okabe_ito() 6 | 7 | p2 <- ggplot(mpg, aes(cty, hwy, color = factor(cyl))) + 8 | geom_point(alpha = 0.7) + 9 | scale_color_okabe_ito(name = "Cylinders", alpha = .9) 10 | 11 | p3 <- ggplot(mpg, aes(hwy, color = class, fill = class)) + 12 | geom_density() + 13 | scale_fill_okabe_ito(name = "Class", alpha = .9) + 14 | scale_color_okabe_ito(name = "Class") 15 | 16 | p4 <- ggplot(mpg, aes(cty, hwy, color = factor(model))) + 17 | geom_point() + 18 | scale_color_okabe_ito() 19 | 20 | expect_error( 21 | ggplot_build(p4), 22 | "Insufficient values in manual scale. 38 needed but only 9 provided." 23 | ) 24 | 25 | expect_doppelganger("Scale color", p1) 26 | expect_doppelganger("Scale color with alpha and name", p2) 27 | expect_doppelganger("Scale f+c, color alpha, joint name", p3) 28 | }) 29 | 30 | test_that("ggraph scales work", { 31 | skip_if_not_installed("ggraph") 32 | skip_if_not_installed("igraph") 33 | skip_on_ci() 34 | 35 | # example from https://www.data-imaginist.com/2017/ggraph-introduction-edges/ 36 | library(ggplot2, warn.conflicts = FALSE) 37 | library(ggraph, warn.conflicts = FALSE) 38 | library(igraph, warn.conflicts = FALSE) 39 | 40 | graph <- graph_from_data_frame(highschool) 41 | pop1957 <- degree(delete_edges(graph, which(E(graph)$year == 1957)), 42 | mode = 'in') 43 | pop1958 <- degree(delete_edges(graph, which(E(graph)$year == 1958)), 44 | mode = 'in') 45 | V(graph)$pop_devel <- ifelse(pop1957 < pop1958, 'increased', 46 | ifelse(pop1957 > pop1958, 'decreased', 47 | 'unchanged')) 48 | V(graph)$popularity <- pmax(pop1957, pop1958) 49 | E(graph)$year <- as.character(E(graph)$year) 50 | 51 | 52 | p1 <- ggraph(graph, layout = 'kk') + 53 | geom_edge_link(aes(colour = as.character(year))) + 54 | scale_edge_color_okabe_ito() 55 | 56 | expect_doppelganger("Edge color", p1) 57 | }) 58 | --------------------------------------------------------------------------------