The goal of paleval is to help you evaluate the effectiveness of color palettes and color maps. It builds from the colorspace package, used to design color maps, and the farver package, used to evaluate the perceptual difference between two colors.
This will have to go into a design-document eventually, but for now, I’ll “puke” this here.
For the purpose of this package, following colorRamp
and ggplot2 usage, we define some classes:
pev_fcont
: A function that describes a continuous palette. When called with a numeric vector with values between 0 and 1, it returns a vector of the corresponding (hex-code) values.
pev_fdisc
: A function that describes a discrete palette. When called with a single integer argument (the number of levels in the scale), it returns a vector of the (hex-code) value for the entire scale. There are two types of discrete-palette functions:
pev_bounded
: Indicates that there is an upper-bound on the number of colors it can provide, e.g. Tableau 10. You would not think to interpolate between these colors.
pev_unbounded
: Indicates that there is no upper-bound on the number of colors it can provide, e.g. "Pastel"
. You might think to interpolate between these colors.
These follow the palette
argument for ggplot2::continuous_scale()
and ggplot2::discrete_scale()
, as well as graphics::colorRamp()
and graphics::colorRampPalette()
, respectively.
I’m suspect I’m doing things in a way that the authors of colorspace
, ggplot2
, farver
, and graphics
might prefer not to consider while eating. As much as anything, this package is an attempt to reationalize and harmonize all of these concepts to myself.
There are ways to create continuous-palette functions:
pev_fcont()
: constructor
pev_fcont
(no-op).pev_fcont_cvd()
: modifies the output of the palette function according to color-vision deficiency.pev_fcont_diverging()
: composes two continuous-palette functions to create (presumably) a diverging palette-function. It’s up to you to make sure the constituent palettes “meet in the middle”.pev_fcont_rescale()
: rescaling an existing continuous-palette function. It may make sense to “zoom-in”, but “zooming-out” could get you into trouble.pev_fcont_reverse()
: reverses the sense of the palette function.There are ways to create discrete-palette functions:
pev_fdisc()
: constructor
pev_fcont
, given a discretization method
(e.g. "panel"
or "post"
), returns an unbounded function.pev_fdisc
(no-op).pev_fdisc_cvd()
: modifies the output of the palette function according to color-vision deficiency.
pev_fdisc_reverse()
: reverses the sense of the palette function.
print()
: prints a representation of the palette function.
Other functions:
pev_nmax()
: get the maximum length supported by a discrete-palette function
pev_hex_distance()
: given two (sets of) hex-colors, hex
, hex_ref
:
distance
between thempev_data_separation()
: assess color-separation, given a discrete-palette function,
data.frame
with cvd
, i
, hex
, hex_ref
, distance
pev_data_derivative()
: assess perceptual-derivative, given a continuous-palette function,
data.frame
with cvd
, x
, hex
, d_distance_d_x
pev_data_distance()
: assess perceptual-distance from a reference-color, given a continuous-palette function,
data.frame
with cvd
, x
, hex
, hex_ref
, distance
pev_data_hcl()
: given hex
, return cvd
, x
, hex
, hue
, chroma
, luminance
, is_boundary
pev_data_hcl_ref()
: given fpal
, hex_ref
, return cvd
, x_nearest
, distance_nearest
, hex
, chroma
, luminance
pev_gg_hcl_bloom()
: given data_hcl
, data_hcl_ref
pev_gg_hcl_plane()
: given data_hcl
, data_hcl_ref
pev_gg_hcl_spectrum()
: given data_hcl
, data_hcl_ref
Here’s a reference on delta E - can we find something more definitive?
You can install the development version of paleval from GitHub with:
library("paleval")
fcont <- pev_fcont("Dynamic") # continuous palette-function, from colorspace
fdisc <- pev_fdisc(fcont, method = "panel") # discrete palette-function
data_sep <- pev_data_separation(fdisc(7))
print(data_sep)
#> # A tibble: 196 x 5
#> cvd i hex hex_ref distance
#> <chr> <int> <chr> <chr> <dbl>
#> 1 none 1 #E396A0 #E396A0 0
#> 2 none 1 #E396A0 #D796D0 14.9
#> 3 none 1 #E396A0 #9FA8E2 26.4
#> 4 none 1 #E396A0 #4CB9CC 53.6
#> 5 none 1 #E396A0 #50BE9B 53.0
#> 6 none 1 #E396A0 #97B56C 45.3
#> 7 none 1 #E396A0 #CBA56E 27.1
#> 8 none 2 #D796D0 #E396A0 14.9
#> 9 none 2 #D796D0 #D796D0 0
#> 10 none 2 #D796D0 #9FA8E2 18.3
#> # … with 186 more rows
pev_gg_separation(data_sep)
data_drv <- pev_data_derivative("Purple-Green")
data_drv
#> # A tibble: 164 x 4
#> cvd x hex d_distance_d_x
#> <chr> <dbl> <chr> <dbl>
#> 1 none 0 #492050 136.
#> 2 none 0.025 #562A5E 152.
#> 3 none 0.05 #65346D 162.
#> 4 none 0.075 #733F7C 169.
#> 5 none 0.1 #82498C 172.
#> 6 none 0.125 #90529C 178.
#> 7 none 0.15 #9F5CAB 187.
#> 8 none 0.175 #AE65BB 170.
#> 9 none 0.2 #B574C2 167.
#> 10 none 0.225 #BD82C9 158.
#> # … with 154 more rows
pev_gg_derivative(data_drv)
data_dist <- pev_data_distance("Purple-Green")
data_dist
#> # A tibble: 164 x 5
#> cvd x hex hex_ref distance
#> <chr> <dbl> <chr> <chr> <dbl>
#> 1 none 0 #492050 #492050 0
#> 2 none 0.025 #562A5E #492050 3.59
#> 3 none 0.05 #65346D #492050 7.58
#> 4 none 0.075 #733F7C #492050 11.7
#> 5 none 0.1 #82498C #492050 16.0
#> 6 none 0.125 #90529C #492050 20.1
#> 7 none 0.15 #9F5CAB #492050 24.7
#> 8 none 0.175 #AE65BB #492050 29.2
#> 9 none 0.2 #B574C2 #492050 33.5
#> 10 none 0.225 #BD82C9 #492050 38.1
#> # … with 154 more rows
pev_gg_distance(data_dist)
data_hcl <- pev_data_hcl("Viridis", n = 41)
data_hcl
#> # A tibble: 164 x 7
#> cvd x hex hue chroma luminance is_rgb_limit
#> <chr> <dbl> <chr> <dbl> <dbl> <dbl> <lgl>
#> 1 none 0 #FDE333 74.8 94.9 89.9 FALSE
#> 2 none 0.025 #EFE32D 80.8 93.6 88.7 FALSE
#> 3 none 0.05 #E1E22B 86.3 92.4 87.3 FALSE
#> 4 none 0.075 #D2E02E 91.7 90.8 85.6 FALSE
#> 5 none 0.1 #C2DE34 97.5 89.4 83.9 FALSE
#> 6 none 0.125 #B2DC3C 103. 88.2 82.4 FALSE
#> 7 none 0.15 #A2D945 109. 86.5 80.6 FALSE
#> 8 none 0.175 #90D74E 115. 85.7 79.1 FALSE
#> 9 none 0.2 #7ED357 120. 83.6 77.1 FALSE
#> 10 none 0.225 #6AD05F 126. 82.6 75.5 FALSE
#> # … with 154 more rows
data_hcl_ref <- pev_data_hcl_ref("Viridis", pev_fcont("Viridis")(0.55))
pev_gg_hcl_bloom(data_hcl, data_hcl_ref)
Please note that the ‘paleval’ project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.