Coder Social home page Coder Social logo

chroma's Introduction

chroma

chroma is a R package for parsing and formating colors in various specifications, manipulating colors, and creating nice color scales and palettes. Much of the functionality is based on the excellent chroma.js javascript library by Gregor Aish.

Installation

chroma is not on CRAN yet. To get it from this page, install the package devtools and

devtools::install_github("jiho/chroma")
library("chroma")

NB: some functions in the chroma package mask functions in basic R packages (e.g. grDevices) or often used ones (e.g. ggplot2). Most of the time, they are argument-compatible with the function they mask and, if their result is different, I would argue that the one in chroma is more correct. If you want to use chroma but would rather not mask the other functions, just install the package but do not load it with library(); instead, just call the functions with the chroma:: prefix (e.g. chroma::rgb() instead of rgb(), to avoid masking rgb() in package grDevices).

Color parsing

Parse colors in various specifications

rgb(r=0.5, g=0.5, b=0.5)
# [1] "#808080"
ryb(r=0.5, y=0.5, b=0.5)
# [1] "#957149"
hsv(h=120, s=0.5, v=0.5)
# [1] "#408040"
hsl(h=120, s=0.5, l=0.5)
# [1] "#40BF40"
hsi(h=120, s=0.5, i=0.5)
# [1] "#40FF40"
hcl(h=120, c=0.5, l=0.5)
# [1] "#638127"
lab(l=0.5, a=-0.5, b=0.2)
# [1] "#008A53"
hex("#393939")
# [1] "#393939"
hex("F39")
# [1] "#FF3399"
css("rgb(100,100,100)")
# [1] "#646464"
temperature(5600)
# [1] "#FFEDE2"
wavelength(500)
# [1] "#178672"

Parse directly from a matrix

x <- matrix(c(0.2, 0.5, 0.5, 0.5, 0.6, 0.4), ncol=3)
print(x)
#      [,1] [,2] [,3]
# [1,]  0.2  0.5  0.6
# [2,]  0.5  0.5  0.4
rgb(x)
# [1] "#338099" "#808066"

Color formating

Convert back in various formats

as.rgb("coral1")
#      r         g         b
# [1,] 1 0.4470588 0.3372549
as.ryb("coral1")
#             r        y          b
# [1,] 0.424082 0.296286 0.08746012
as.hsv("coral1")
#             h         s v
# [1,] 9.940828 0.6627451 1
as.hsl("coral1")
#             h s         l
# [1,] 9.940828 1 0.6686275
as.hsi("coral1")
#            h        s         i
# [1,] 8.89147 0.432967 0.5947712
as.hcl("coral1")
#             h         c         l
# [1,] 38.74251 0.6651031 0.6494095
as.lab("coral1")
#              l        a         b
# [1,] 0.6494095 0.518758 0.4162358
as.hex("coral1")
# [1] "#FF7256"
as.css("coral1")
# [1] "RGB(255,114,86)"
as.temperature("coral1")
# [1] 2686
as.wavelength("coral1")
# [1] 616

Color manipulation

Slightly modify a base color

col <- "#7BBBFE"
show_col(c(col, brighten(col), darken(col)))

show_col(c(col, desaturate(col), saturate(col)))

Make a color semi-transparent

col <- "#7BBBFE"
show_col(c(col, alpha(col), alpha(col, 0.2)))

Mix or blend two colors

show_col(c("#7BBBFE", "#FDFF68", mix("#7BBBFE", "#FDFF68")))

show_col(c("#7BBBFE", "#FDFF68", blend("#7BBBFE", "#FDFF68")))

show_col(c("#7BBBFE", "#FDFF68", blend("#7BBBFE", "#FDFF68", mode="screen")))

Compute the contrast between two colors

contrast("darkblue", "darkgreen")
# [1] 2.056261
contrast("yellow", "darkgreen")
# [1] 6.927705

Compute the euclidean or perceptual distance between two colors (following the CIE Delta E 2000 formula)

# pick three colors; lightgreen is closer to darkgreen that darkblue is
show_col(c("darkblue", "darkgreen", "lightgreen"))

color_distance("darkblue", "darkgreen")
# [1] 146.5474
color_distance("lightgreen", "darkgreen")
# [1] 50.67107
CMClc("darkblue", "darkgreen")
# [1] 81.42556
CMClc("lightgreen", "darkgreen")
# [1] 35.98541
deltaE("darkblue", "darkgreen")
# [1] 57.91349
deltaE("lightgreen", "darkgreen")
# [1] 43.52127

which allows to find the closest perceived color in a array of possibilities

target <- "limegreen"
choices <- rainbow(10)
closest_color <- choices[which.min(deltaE(target, choices))]
show_col(target, choices, closest_color)

Extract or set a color channel

col <- "#7BBBFE"
channel(col, model="hcl", "h")
#        h 
# 266.7734
channel(col, model="hsv", "s")
#        s 
# 0.515748
channel(col, model="hsi", "i")
#         i 
# 0.7372549
channel(col, model="rgb", "r")
#         r 
# 0.4823529
col1 <- col2 <- col
channel(col1, model="hcl", "h") <- 120
channel(col2, model="hcl", "l") <- 1
show_col(c(col, col1, col2))

Compute or set the perceived luminance of a color

luminance(c("red", "yellow", "darkblue"))
# [1] 0.2126000 0.9278000 0.0186408
col1 <- col2 <- col <- "#7BBBFE"
luminance(col)
# [1] 0.4690736
luminance(col1) <- 0.6
luminance(col2) <- 0.2
show_col(c(col, col1, col2))

Color scales and palettes

All scales and palettes are organised the same way:

  • functions ending in *_scale return a function that takes a numeric vector x as argument and returns the corresponding colors in the scale.
  • functions ending in *_map are shortcuts that build the scale, map the values, and return the colors.
  • functions ending in *_palette return a function that takes an integer n as argument and returns n equally spaced colors along the scale.
  • functions ending in *_colors are shortcut that create the palette and return the n colors.
x <- 0:10/10
s <- interp_scale()
s(x)
#  [1] "#FFFFFF" "#E2E2E2" "#C6C6C6" "#ABABAB" "#919191" "#777777" "#5E5E5E"
#  [8] "#474747" "#303030" "#1B1B1B" "#000000"
# or
interp_map(x)
#  [1] "#FFFFFF" "#E2E2E2" "#C6C6C6" "#ABABAB" "#919191" "#777777" "#5E5E5E"
#  [8] "#474747" "#303030" "#1B1B1B" "#000000"
n <- 11
p <- interp_palette()
p(n)
#  [1] "#FFFFFF" "#E2E2E2" "#C6C6C6" "#ABABAB" "#919191" "#777777" "#5E5E5E"
#  [8] "#474747" "#303030" "#1B1B1B" "#000000"
# or
interp_colors(n)
#  [1] "#FFFFFF" "#E2E2E2" "#C6C6C6" "#ABABAB" "#919191" "#777777" "#5E5E5E"
#  [8] "#474747" "#303030" "#1B1B1B" "#000000"

Palettes can be built by interpolating between colors

show_col(interp_colors(10))

show_col(interp_colors(10, colors=c("#2D2B63", "#F7FF84")))

show_col(interp_colors(10, colors=c("#2D2B63", "#FB3C44", "#F7FF84")))

For the perception of “change” along the scale to be more linear, colors can be interpolated using bezier curves and their lightness can be corrected.

show_col(interp_colors(10, colors=c("#2D2B63", "#FB3C44", "#F7FF84")))

show_col(interp_colors(10, colors=c("#2D2B63", "#FB3C44", "#F7FF84"), interp="bezier"))

show_col(interp_colors(10, colors=c("#2D2B63", "#FB3C44", "#F7FF84"), interp="bezier", correct.lightness=TRUE))

Preset palettes are available, from colorbrewer

show_col(lapply(brewer_info$name, function(x) {brewer_colors(n=7, name=x)}))

Or viridis

show_col(
  viridis_colors(10),
  magma_colors(10),
  plasma_colors(10),
  inferno_colors(10)
)

Or cubehelix

show_col(
  cubehelix_colors(10),
  cubehelix_colors(10, h=300, rot=-0.75),
  cubehelix_colors(10, h=120, rot=0.5),
  cubehelix_colors(10, h=300, rot=0.5)
)

Or ETOPO1 and Wikipedia for topographical maps

show_col(
  etopo_colors(100),
  wikitopo_colors(100)
)

Custom, perceptually appropriate, palettes can be built in HCL space, for either discrete

show_col(hue_colors(10))

or continuous variables

show_col(chroma_colors(10, h=140))

show_col(light_colors(10, h=140))

Helper functions

Additional functions are included to facilitate the use of the color scales in base and ggplot2 plots.

sidemargin() and sidelegend() allow to place legends on the side of base plots

attach(iris)
# make larger right margin
pars <- sidemargin()
# plot the data with a nice color scale
plot(Petal.Length, Petal.Width, col=hue_map(Species), pch=19)
# add a legend for the scale on the side
sidelegend(legend=levels(Species), col=hue_colors(nlevels(Species)), pch=19)

# set graphical parameters back to default
par(pars)
detach(iris)

persp_facets() allows to compute the colors for each facet of a persp() plot

persp(maunga, theta=50, phi=25, scale=FALSE, expand=2,
      border=alpha("black", 0.4),
      col=magma_map(persp_facets(maunga$z)))

Various scale_color_*() and scale_fill_*() functions allow to use the color scales defined in chroma directly with ggplots and scale_xy_map() draws nice x and y scales for maps.

ggplot(iris) +
  geom_point(aes(Petal.Length, Sepal.Length, color=Species)) +
  scale_color_cubehelix_d(h=0, rot=0.75, c=1, l=c(0.6, 0.6))

ggplot(thaixyz) + coord_quickmap() +
 geom_raster(aes(x, y, fill=z)) +
 scale_fill_wikitopo() + scale_xy_map()


Happy coloring!

chroma's People

Contributors

flrd avatar jiho avatar lirogers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

chroma's Issues

Consider adding LaTeX beamer colors

While this would be useful to color match the theme in latex presentations, those palettes are not for graphical representation of continuous variables and maybe only valid for a small number of categorical levels. Even then, there is no argument for their perceptual value.

To be considered together with adding support for other palettes.

beamer colors.zip

beamer_colors.txt

TypeError: Object ... has no method 'includes

Hi

You might already know it, but just in case: I tried the dev version, and now face some errors...

Thanks!!

devtools::install_github("jiho/chroma")
#> Skipping install of 'chroma' from a github remote, the SHA1 (c24168e5) has not changed since last install.
#>   Use `force = TRUE` to force installation
library("chroma")
#> 
#> Attaching package: 'chroma'
#> The following objects are masked from 'package:grDevices':
#> 
#>     hcl, hsv, rgb
show_col(interp_colors(6, colors=c("#002855", "#DAAA00")))
#> Error in context_eval(join(src), private$context): TypeError: Object 3,4,6,7,8,9 has no method 'includes'

Created on 2019-07-25 by the reprex package (v0.3.0)

equivalent of .correctLightness() in chroma?

Hi

Thanks for this nice package! I was looking at the post on chroma.js(), where they talk a lot about the lighntess correction, showing for example this piece of code:

chroma.scale(['white', 'yellow', 'red', 'black'])
   .correctLightness();

Is this function also available in the R package?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.