jamba
to Imports, from Depends, for cleaner R code.named_colors
to v11.0.0 from "meodai/color-names"
blend_colors()
apply_alpha=TRUE
will apply alpha transparency to
multiple colors, returning a blended color with appropriate
transparency.
The goal was to blend transparent red with itself and produce
less transparent red.flatten_alpha
will optionally flatten any blended
color transparency using the background color bg
.
The goal was to convert transparent red (see above) to light red
equivalent to transparent red on white background.bg
is used only when flatten_alpha=TRUE
, for
background color other than white.closest_named_colors()
now uses proper colorjam::named_colors
to fix error when calling colorjam::closest_named_colors()
without
loading the colorjam package first.
blend_colors()
: Fixed error when matrixStats
was not installed.testthat
coverage for core functions.blend_colors()
was not properly using preset
options("jam.preset")
had already been defined, it would
take priority during color blending.preset="custom"
internally.preset
values to permit all values in
colorjam_presets()
.launchColorjamShiny()
jamba
was not already loaded, added proper package prefix:
jamba::kable_coloring()
subset_colors()
jamba::rgb2col()
rainbowJam()
jamba::col2hcl()
named_colors
- fixed missing named using data-raw/named_colors.R
@source
to named_colors
to Github "meodai/color-names"data-raw/
to prepare named_colors
preset="dichromat2"
rainbowJam()
min_requested_n
previously used internally,
exposed for testing the minimum requested hues.
Secretly used to ensure the first 5 or so colors are pretty..onLoad()
to add default options(colorjam.preset="dichromat2")
,
and which can be customized.sort_colors()
byCols=NULL
changed to byCols=c("H", "C", "L")
so
the default behavior will sort colors by hue, previously the
default behavior was not to sort colors, which seemed counter
to the default purpose of the function.new preset "hcl_to_hsl"
intended for internal use to convert HCL hue
to HSL hue.
launchColorjamShiny()
"none"
, "hcl_to_hsl"
remap_colorjam_preset()
hcl_to_hsl_hue()
,hsl_to_hcl_hue()
Added MIT license and copyright.
dichromat
added as package dependency. Respect.cli
was added as a package dependency (in v24 actually),
to be consistent with recommended R package messaging.Each preset
now includes direction
and default_step
, optional
attribute "description"
as a label.
preset
is designed with
a step
in mind, so the appropriate default_step
should be storeddirection
was previously deduced by the h1
,h2
values,
however this too is unnecessary and should be encoded in the preset
to avoid errors.For my own benefit, I made a simple R-shiny app:
rainbowJam()
n
, preset
, step
preset
control points, creating a new color wheelI used the R-shiny app to create and optimize dichromat2
:
n
.named_colors
Superset of 4883 hexadecimal colors with corresponding color names:
"meodai/color-names"
repository;grDevices::colors()
, which were not already
defined by Meodai colors.Colors are intended to improve labeling rainbowJam()
colors.
closest_named_color()
could become a QC step
to confirm that rainbowJam()
creates colors that can be assigned
to different named colors.grDevices::colors()
did not provide sufficient detail,
specific examples frequently included "cornflowerblue"
and "steelblue"
despite appearing for colors with visibly distinctive blue/purple
color hues.launchColorjamShiny()
'
, preset
, step
, phase
, subset
h1
and h2
values, which can be edited!
Is it not perfect, need to override plotly "snap" behavior,
which seems to be hard-coded.dichromat::dichromat()
adjustment to simulate color-blindnesscolorjamShinyServer()
,colorjamShinyUI()
are internal functions
to provide server
and ui
components to shiny::runApp()
.closest_named_color()
closestRcolor()
except that it uses the 4883
named_colors
instead of R grDevices::colors()
, although all
colors are contained in named_colors
.validate_colorjam_preset()
h1
,h2
values, wrap within range c(0, 360)
direction=1
and direction=-1
h1
,h2
when out of order. E.g. is one point
is adjusted past the next point, the next point should be shifted.plot_colorjam_preset()
h1
,h2
values, showing the resulting color
along each respective axis.vibrant_color_by_hue()
rainbowJam()
nameStyle="closest_named_color"
which uses
the 4883 named_colors
for labeling.nameStyle="hcl"
now calculates actual HCL values and not the
input values to hcl()
, because those values may change upon
creating a color in gamut.h1
,h2
are deprecated, instead use preset
Cvals
,Lvals
are deprecated, instead use step
phase
can take one or more values, to select and order specific
items in the given step
colorjam_presets()
,add_colorjam_preset()
preset
now also has direction
and default_step
.h2hw()
,hw2h()
colorjam_presets()
approx_degrees()
preset
inputdirection
instead of determining by h1
,h2
validate_colorjam_preset()
to handle tie-breaksclosestRcolor()
colorSet
has names, helpful with the
reference colors are hex, and names are user-friendly labels.This version of colorjam turned into a bit of a refactor:
Color wheels are now stored as "presets":
colorjam_presets()
colorjam_presets("dichromat")
add_colorjam_preset()
options("colorjam.preset")
Rainbow colors are adjusted by Chroma/Luminance "steps":
list
with numeric
vectors named "C"
and "L"
,
each with values within the range: c(0, 100)
.colorjam_steps()
, colorjam_steps("v24")
add_colorjam_step()
options("colorjam.step")
Background:
rainbowJam()
used arguments Cvals
and Lvals
to apply
a sequence of luminance/chroma values to a series of color hues.
The variation in C and L values was intended to maximize
visual distinctiveness of consecutive colors.
In fact, this process was the inspiration for colorjam
,
to make rainbow catgorical colors more visually distinctive
than comparable functions that notably intend to produce colors
as similar as possible. Different motivations.colorspace::rainbow_hcl(n, c, l)
accepts only one value per
c
and l
argumentgrDevices::rainbow()
uses the non-uniform hsv
color space,
and accepts multiple values for arguments s
and v
.
(To be fair, the hcl.colors()
Altogether rainbowJam()
defines categorical colors with two core elements:
"preset"
: color wheel with starting color, to define the color hues."steps"
: series of Chroma/Luminance values to apply to color hues.Starting color:
After very heavy usage of this package, it became clear that assigning categorical colors to statistical designs was not ideal. Specifically, we standardized experiment designs so that "the control" for each experiment factor is the first value in each column.
c("Control", "Dexamethasone", "Etoposide")
;
c("Wildtype", "ADAM19_Knockout")
;
c("Time0", "Time1", "Time2", "Time3")
The new presets include:
"dichromat2"
which starts with gold, proceeds in reverse to
red, purple, blue. (There is no green in the dichromat color wheel.)"ybr"
derived by "ryb"
except it starts with yellow,
proceeds "forward" to green, blue, purple, then red.Added cli
package dependency for improved messaging, particularly for
deprecated function arguments.
jam_linear
and jam_divergent
data objects.rainbowJam()
preset
is the primary definition of color wheelCvals
,Lvals
,Crange
,Lrange
are deprecated
(frankly, who is affected though, only me)h1
,h2
are deprecated and ignored in favor of preset
.
To use custom h1
,h2
they must be added to new preset then referred
by name.new argument step
defines the sequence of C
and L
values
"v19"
, "v20"
, "v23"
, and "v24"
.colorspace
and farver
handle by adjusting other color channels;
sometimes substantially changing the output color hue.
This change sometimes caused the color hue sequence to reverse itself
to accommodate the requested C
and L
values, and was the driving
use case for the refactored arguments preset
and steps
.color_pie()
jamba::shadowText()
and jamba::setTextContrastColor()
closestRcolor()
Cgrey
to recognize when input x
colors are greyscale,
in which case they are matched with colors from colorSet
which are
below C_min
Chroma saturation. By default, color matching is much
improved when using a mix of saturated and unsaturated colors.scale_color_jam()
,scale_fill_jam()
,jam_pal()
h1
,h2
(before they
could be used), and added argument step
.preset="dichromat2
consistent with rainbowJam()
.h2hw()
,hw2h()
,h2hwOptions()
preset=getOption("colorjam.preset", "custom")
behaves as previous preset="custom"
except that it now honors
when the option "colorjam.preset"
is defined.preset
are with blend_colors()
and
closestRcolor()
which both default to "ryb"
because those specific
use cases favor using the red-yellow-blue color wheel.approx_degrees()
make_jam_divergent()
linear2
is not supplied, it calls
color_complement()
to determine a reasonable opposing color,
so one can call make_jam_divergent("red")
and it will provide
a reasonableadjust_hue_warp()
colorjam_preset()
,add_colorjam_preset()
colorjam_step()
,add_colorjam_step()
h2hwOptions()
colorjam_presets()
instead of using internal values.jamba (>= 0.0.83.900)
to include hsl2col()
, col2hsl()
subset_colors()
now calls colors_to_df()
to create a data.frame
,
any of whose columns can be used to sort colors.theme_jam()
changes:
new argument strip.text.size
with default ggplot2::rel(0.8)
to help adjust facet panel strip text font size directly.
new argument panel.border
to make adjustments convenient,
by default panels now have thin dark gray outline.
Set panel.border=NULL
to hide the border.
scale_color_jam()
, scale_fill_jam()
, jam_pal()
:
new argument darken
is logical
, when darken=TRUE
it automatically
sets darkFactor
and sFactor
to reasonable values for subtle darkening.
This option is convenient for slightly darker outlines around points.
colors_to_df()
convert vector of colors to data.frame
with column
values representing several common colorspace formats. Note that
HSL color dimensions have prefix "hsl_"
, for example "hsl_h"
,
"hsl_s"
, and "hsl_l"
.
For some reason, the H hue values in HCL
do not match the hue values in HSL, despite both being angles with
range c(0, 360)
. Fun.
sort_colors()
applied sort criteria to data returned by colors_to_df()
.
I anticipate the rainbowJam()
function will shift from using HCL,
instead to using HSL for color selection.
Summary of thought process so far:
rainbowJam()
uses "tricked out" C and L sequences, that request
higher C chroma than possible for most hues, causing it to return
higher saturation than typical. Meanwhile the L values help create
6 distinct colors for every hue.n
is high,
sometimes a series of colors have nearly identical hue due to
the conversion issues described above."yellow"
are effectively
lost, since it is brighter with higher chroma than other color hues
No C,L sequence could permit using yellow and other color hues with
these C and L values. Large swaths of beautiful colors would never
be chosen for categorical color sets, and we just cannot have that.
Cue the "de Blob" video game cut scene.approx_degrees()
was calling tcount()
from the jamba
package, and because the jamba
package is listed as "Depends"
its functions are loaded and available to colorjam
once
it is loaded. However, for some curious reason in R internals,
when the function is called directly colorjam::approx_degrees()
it does not import jamba
functions, therefore jamba::tcount()
is not available, and it throws an error. The issue was
reported via the venndir
package, where default usage of
venndir
causes an error for the most basic operations.
The workaround is to load colorjam or jamba first, however
the real fix is to include package prefix here.A new hue warp preset is available, a fully corrected "red-yellow-blue"
gradient which is intended to provide full color complement
capability. However, rainbowJam()
is preparing for a larger
update that focuses on choosing colors within gamut for each
color hue. The colorspace
and farver
color conversion functions
are able to provide colors outside of gamut but altering some
components which ultimately change the hue. As a result, the
hue sequence from rainbowJam()
is sometimes out of order
due to that correction. A new method that returns strictly
correct hue within gamut is being tested and will be applied
in an upcoming release.
New default preset="custom"
is used in several functions,
which will re-use any defined h1
and h2
values
in options("h2hw.h1")
and options("h2hw.h2")
,
otherwise it will use default_preset="dichromat"
.
For the default scenario, nothing will change. When
a custom h1
and h2
should be used, it will be easier
for it to be applied by default. Setting preset
to any
named value will override any stored h1
and h2
values.
rainbowJam()
argument value changed hue_pad_percent=0
,
subtle change that means there is less color buffer between
the first and last color in the hue sequence. This argument
was most useful as a partial workaround to the color hue
gamut conversion "bug" in colorspace and farver. Not technically
a bug, as it is documented behavior, but the output is
not what one would expect imo.approx_degrees()
was modified to simplify the logic, and to
handle special cases like inverted angles, and rotated angles.h2hwOptions()
, h2hw()
, hw2h()
, and rainbowJam()
default
argument changed to preset="custom"
which will preserve any
pre-existing h1,h2
values, otherwise a named preset
will
take priority and define h1,h2
values directly.scale_color_jam()
, scale_fill_jam()
, jam_pal()
were updated
to use preset="custom"
by default, and to pass h1
and h2
arguments.New option:
options("colorjam.preset")
as a convenient way to maintain
the current preset.closestRcolor()
and twostep_gradient()
were updated
to use proper package prefixing to the jamba
package.scale_color_jam()
and scale_fill_jam()
no longer require(ggplot2)
,
and use jamba::check_pkg_installed()
to test whether ggplot2 is
available. Added examples for both.theme_jam()
no longer require(ggplot2)
and now properly
calls ggplot2::theme_classic()
with argument resetTheme=TRUE
.rainbowJam()
arguments Lvals
and Cvals
were updated,
making the categorical palette brighter overall,
with more color saturation, and visible distinction
in neighboring colors at higher n
values. The
examples in rainbowJam()
were updated to show a
before and after comparison.rainbowJamMulti()
is intended to extend rainbowJam()
specifically when a list of categorical colors should be
created at once, in a way that prevents duplicate colors.Several new functions, and two new data objects with color gradients; pkgdown site documentation was updated to showcase several new visual examples in for the new color functions.
scale_color_jam()
, scale_fill_jam()
and jam_pal()
have a new
argument preset
which is passed along to rainbowJam()
to
define the color hue wheel preset. The default preset="dichromat"
uses color blind friendly color hue wheel (mainly by omitting green).
The full rainbow can be used with preset="ryb"
which uses
the enhanced red-yellow-blue color hue wheel, where green
is a secondary color between yellow and blue. The default
R red-green-blue color hue wheel can be used with preset="rgb"
although this palette is optimal for computer monitor use of RGB,
and not at all optimal for human perception, even
among those who can see the full rainbow of color hues.subset_colors()
is a subset function for a vector of R colors,
which allows rapid operations on any RGB, HCL, or HSV attribute.col_div_xf()
produces a color function that maps numeric
values to divergent color gradient. Its arguments define the
numeric range, and optional floor. The floor is a range below
which the absolute numeric value is assigned the middle color,
useful to represent visual whether a point meets a numeric
threshold. This function is motivated to be used with argument "col"
in ComplexHeatmap::Heatmap()
, to define a numeric range
with zero as the fixed mid-point associated with divergent
colors.
The name of the function is derived as follows:
col
matching the argument in ComplexHeatmap::Heatmap()
"col"
div
for divergent colorsx
for the x
-defined numeric rangef
for ability to apply a numeric floorcol_linear_xf()
is the linear/sequential color equivalent
to col_div_xf()
. It is useful for two features:
make_jam_divergent()
creates a divergent color gradient with
lite (white) or dark (black) middle color as appropriate. It can
recognize one of the new Jam gradients from jam_linear
or `jam_divergent
(see below).
twostep_gradient()
is a simple but fairly exciting new function
that produces a linear/sequential color gradient - which means it
proceeds from a baseline color to the saturated color - while also
applying two intermediate color gradients to improve visual
perception. Most gradients from RColorBrewer
employ this technique
to expand the range of colors, and to improve visibility of
each color step by varying both the brightness, and the color hue.
See examples for visual illustrations.Two new color gradient objects are added, and are still under some
development as they are being used to gain feedback. They are both
motivated by the use case of providing color gradients for
genome sequence coverage heatmaps, provided by "platjam"
package
which extends Bioconductor EnrichedHeatmap
, itself an extension
by author of ComplexHeatmap
.
These colors aim to provide color-blind-friendly color gradients,
while providing some utility of categorical coloring for different
panels of a coverage heatmap. Essentially these colors avoid the
range of green hues, which vastly improves visual distinctiveness
for the three color blindness forms emulated by
dichromat::dichromat()
.
jam_linear
is a new R list
object that contains a set of
linear color gradients with white background color. These are
intended to be paired with jam_divergent
. The names in jam_linear
are also used in jam_divergent
.jam_divergent
is a new R list
object that contains a set of
divergent color gradients with black background color to distinguish
itself from jam_linear
. The names in jam_divergent
are also
used in jam_linear
.blend_colors()
was updated to handle blending entirely grey sets
of colors. Previously they failed to blend because the lack of any
color saturation also have them zero weight.blend_colors()
new argument c_floor
defines the C
chroma
color saturation floor, below which a color is considered to have
no color hue. Technically it is given hue weight 0.0001.mean_angle()
had bare reference to jamba::deg2rad()
which
was fixed. This fixed an error in blend_colors()
when the
jamba
was not attached.blend_colors()
performs paint color mixing, very close
to subtractive color blending with some modifications to
account for red-yellow-blue color wheel. It can mix more
than two colors, and accounts for color transparency.
This function currently performs better than any other
color mixing function I am aware of in R -- judged by
the tendency to return what is "expected" in more
cases than not.mean_angle()
takes a vector of angles in degrees,
optionally with weights, and returns the average angle
along with the new radius. Internally it takes the
average unit vector (scaled by weights if supplied).rainbowJam()
was modified to clean up the internal workflow.
Specifically, the argument preset
is more prominent,
making it easy to call rainbowJam(5, preset="ryb")
for
example. The hue padding was also modified to reduce most
cases to zero padding -- this padding added separation
between the first and last color hues in a sequence,
to prevent them from being too similar when the Cvals
and Lvals
sequence was not optimal.rainbowJam()
new argument phase
allows shifting
the Cvals
,Lvals
sequence by steps, or to reverse the
sequence, in order to create more varied color sets.h2hw()
and hw2h()
functions have new argument
preset
which calls h2hwOptions()
and uses the appropriate
color wheel. This change makes it easier to convert
color hues with h2hw(60, preset="ryb")
to convert
default RGB yellow (hue=60) to RYB yellow (hue=120).closestRcolor()
argument preset
defaults to ryb
,
to avoid using dichromat
for closest-color calculations.rainbowJam()
arguments Lvals
and Cvals
were
manually adjusted based upon initial usage and feedback.h2hwOptions()
was refactored to have a cleaner workflow.
It explicitly defines getOptions()
in default argument
values, which can be replace by defining preset
. There
is new argument default_preset
so the first time
this function is called, it knows which preset to use
for initial values.group2colors()
fixed a longstanding bug where
input values that contain ""
would return NA
with NA
name. This occurs from
referencing a vector using name ""
which R forces
to return NA
. Instead group2colors()
now uses
match(x, names(colors))
which works properly.There will almost certainly be more changes, after
using the updated rainbowJam()
for a while and
experiencing the cascade effects. For now, I had
to make some changes, to force me to continue making
more changes as needed.
After using the updated rainbowJam()
for a few months,
a few things became clear:
rainbowJam(n + 20)
and hand-pick colors from the set.
That is almost exactly the problem I was originally trying
to solve with rainbowJam()
, which means the function
was failing.rainbowJam()
padded the end of
the hue sequence to avoid having similar first and last color,
with identical C,L values. When that happened, it added an
aggressive hue pad so the colors would still differ. Long
story short, there weren't enough beautiful purples and pinks.Overall changes:
h2hwOptions()
defines custom color wheels, by adjusting
the hue from rgb to any non-linear sequence. It has new argument
preset
with some named shortcut options: "rgb"
the R default;
"ryb"
the previous red-yellow-blue, which still includes green;
"dichromat"
new option that removes green altogether, and spaces
the remaining hues based upon my perceived consistent visible
distinctiveness between steps. I tried to adjust for effects
simulated by dichromat::dichromat()
for the three types
it provides.h2hwOptions()
new default is preset="dichromat"
! Substantial
change, no more green colors. To change back call h2hwOptions(preset="ryb")
or h2hwOptions(preset="rgb")
. shudderrainbowJam()
argument Cvals
was uniformly increased by 30. It
turns out the conversion from HCL already handles values too high,
by favoring luminance over chroma -- meaning when we request a certain
brightness, we get that brighness even at the expense of lower
chroma (saturation.) Thus most of the work is done by the Lvals
luminance, and the chroma should generally be as high as feasible
with few adjustments.rainbowJam()
by default does not pad the last hue color. Instead
the preset="dichromat"
default in h2hwOptions()
adjusts the
hues from 300 to 360 (which were almost nearly identical pink anyway)
to take up less of the color wheel.rainbowJam()
flipped the 2nd and 3rd values in Lvals
. Even when
calling rainbowJam(4, preset="ryb2")
, it won't give the same results
as before this update, without also changing the 2nd and 3rd values in
Lvals
. I realize, only I care.rainbowJam()
was refactored to address longstanding
critique that the colors were too muddy. New logic
is present in rainbowJam()
and the previous function
is available with rainbowJam_v1()
for backward
compatibility. The new colors are much brighter and
will need testing over time to evaluate the effects on
downstream uses. That said, the colors are so much
improved, it seems reasonable to replace the previous
function for now.color_pie()
is a simple function to display colors in
pie chart form, which is helpful to assess the first and
last color in a rainbow color ramp. In fact, color_pie()
might be moved into jamba::showColors()
as an optional
output format. Current challenge is how to label each ring,
when the input is a list of color vectors.theme_jam()
was updated to make the major and minor grid
lines a lighter shade of gray, so they have less interference
with text labels on a plot panel.scale_fill_jam()
, scale_color_jam()
, and jam_pal()
have
an argument alpha
to control alpha transparency, on a scale of
0 (transparent) to 1 (non-transparent.)closestRcolor()
was updated to handle new behavior from col2hcl()
which by default does not assign names to unnamed vectors.closestRcolor()
now has method
argument to define the distance
method (see stats::dist()
); added optional "LUV" color model. In some
cases "LUV" has greater sensitivity albeit with less accuracy. In other
words for large color vectors, "LUV" may produce the most non-repeated
colors at cost of accuracy, while "hcl" tends to be more accurate but
sometimes snaps two similar colors to the same closest R color.
Future work should probably handle greyscale colors separately.vals2colorLevels()
was updated to handle edge cases where input
values had no numeric range.vals2colorLevels()
converts a numeric vector into a color gradient,
optionally divergent around a baseline, optionally applying the color
warp using jamba::warpRamp()
and a lens
adjustment value.matrix2heatColors()
to apply color gradient to each column in a matrix,
where each column has its own color scale.theme_jam()
which provides a Jam-specific ggplot2 default.scale_color_jam()
, scale_fill_jam()
, and jam_pal()
provide
categorical colors and fills, respectively, using rainbowJam()
.closestRcolor()
to fix a small bug with name handling
of the output.group2colors()
takes a vector of group labels and assigns
categorical colors, by default using rainbowJam()
but which
can be substituted with other color functions as needed. It
maintains order of factor levels, otherwise uses jamba::mixedSort()
to order unique labels before assigning colors.closestRcolor()
finds the closest named R color from
colors()
and returns that name. It can also be given a custom
color vector, and will return the closest color for each color
in the input list.rainbowJam()
is the key categorical color function for
the JAM package suite. It uses Red-Yellow-Blue color wheel,
and uses a pattern of alternating Chroma (color saturation) and
Luminance (visible brightness) to maximize the difference between
adjacent colors.Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.