The simple R perspective on colours:

Colour Palette: A sequence of RGB or HEX colours (think Selection of neat paints applied directly undiluted)

Colour Ramp: Graduated mixture through a palette. One Dimensional colour space over a specified spectrum/sequence (defined by a Palette) of colours

Colour: sampled point of a Colour Ramp (what’s shown on screen/applied to the brush) represented in two ways - RGB defined by a tuple (vector) of RGB values - HEX a six-digit hexadecimal (base-16) format #RRGGBB

2-D colour spaces are handled using bilinear interpolation

Oil painting palette
Oil painting palette

Available Colours

basic colours
colours()
##   [1] "white"                "aliceblue"            "antiquewhite"        
##   [4] "antiquewhite1"        "antiquewhite2"        "antiquewhite3"       
##   [7] "antiquewhite4"        "aquamarine"           "aquamarine1"         
##  [10] "aquamarine2"          "aquamarine3"          "aquamarine4"         
##  [13] "azure"                "azure1"               "azure2"              
##  [16] "azure3"               "azure4"               "beige"               
##  [19] "bisque"               "bisque1"              "bisque2"             
##  [22] "bisque3"              "bisque4"              "black"               
##  [25] "blanchedalmond"       "blue"                 "blue1"               
##  [28] "blue2"                "blue3"                "blue4"               
##  [31] "blueviolet"           "brown"                "brown1"              
##  [34] "brown2"               "brown3"               "brown4"              
##  [37] "burlywood"            "burlywood1"           "burlywood2"          
##  [40] "burlywood3"           "burlywood4"           "cadetblue"           
##  [43] "cadetblue1"           "cadetblue2"           "cadetblue3"          
##  [46] "cadetblue4"           "chartreuse"           "chartreuse1"         
##  [49] "chartreuse2"          "chartreuse3"          "chartreuse4"         
##  [52] "chocolate"            "chocolate1"           "chocolate2"          
##  [55] "chocolate3"           "chocolate4"           "coral"               
##  [58] "coral1"               "coral2"               "coral3"              
##  [61] "coral4"               "cornflowerblue"       "cornsilk"            
##  [64] "cornsilk1"            "cornsilk2"            "cornsilk3"           
##  [67] "cornsilk4"            "cyan"                 "cyan1"               
##  [70] "cyan2"                "cyan3"                "cyan4"               
##  [73] "darkblue"             "darkcyan"             "darkgoldenrod"       
##  [76] "darkgoldenrod1"       "darkgoldenrod2"       "darkgoldenrod3"      
##  [79] "darkgoldenrod4"       "darkgray"             "darkgreen"           
##  [82] "darkgrey"             "darkkhaki"            "darkmagenta"         
##  [85] "darkolivegreen"       "darkolivegreen1"      "darkolivegreen2"     
##  [88] "darkolivegreen3"      "darkolivegreen4"      "darkorange"          
##  [91] "darkorange1"          "darkorange2"          "darkorange3"         
##  [94] "darkorange4"          "darkorchid"           "darkorchid1"         
##  [97] "darkorchid2"          "darkorchid3"          "darkorchid4"         
## [100] "darkred"              "darksalmon"           "darkseagreen"        
## [103] "darkseagreen1"        "darkseagreen2"        "darkseagreen3"       
## [106] "darkseagreen4"        "darkslateblue"        "darkslategray"       
## [109] "darkslategray1"       "darkslategray2"       "darkslategray3"      
## [112] "darkslategray4"       "darkslategrey"        "darkturquoise"       
## [115] "darkviolet"           "deeppink"             "deeppink1"           
## [118] "deeppink2"            "deeppink3"            "deeppink4"           
## [121] "deepskyblue"          "deepskyblue1"         "deepskyblue2"        
## [124] "deepskyblue3"         "deepskyblue4"         "dimgray"             
## [127] "dimgrey"              "dodgerblue"           "dodgerblue1"         
## [130] "dodgerblue2"          "dodgerblue3"          "dodgerblue4"         
## [133] "firebrick"            "firebrick1"           "firebrick2"          
## [136] "firebrick3"           "firebrick4"           "floralwhite"         
## [139] "forestgreen"          "gainsboro"            "ghostwhite"          
## [142] "gold"                 "gold1"                "gold2"               
## [145] "gold3"                "gold4"                "goldenrod"           
## [148] "goldenrod1"           "goldenrod2"           "goldenrod3"          
## [151] "goldenrod4"           "gray"                 "gray0"               
## [154] "gray1"                "gray2"                "gray3"               
## [157] "gray4"                "gray5"                "gray6"               
## [160] "gray7"                "gray8"                "gray9"               
## [163] "gray10"               "gray11"               "gray12"              
## [166] "gray13"               "gray14"               "gray15"              
## [169] "gray16"               "gray17"               "gray18"              
## [172] "gray19"               "gray20"               "gray21"              
## [175] "gray22"               "gray23"               "gray24"              
## [178] "gray25"               "gray26"               "gray27"              
## [181] "gray28"               "gray29"               "gray30"              
## [184] "gray31"               "gray32"               "gray33"              
## [187] "gray34"               "gray35"               "gray36"              
## [190] "gray37"               "gray38"               "gray39"              
## [193] "gray40"               "gray41"               "gray42"              
## [196] "gray43"               "gray44"               "gray45"              
## [199] "gray46"               "gray47"               "gray48"              
## [202] "gray49"               "gray50"               "gray51"              
## [205] "gray52"               "gray53"               "gray54"              
## [208] "gray55"               "gray56"               "gray57"              
## [211] "gray58"               "gray59"               "gray60"              
## [214] "gray61"               "gray62"               "gray63"              
## [217] "gray64"               "gray65"               "gray66"              
## [220] "gray67"               "gray68"               "gray69"              
## [223] "gray70"               "gray71"               "gray72"              
## [226] "gray73"               "gray74"               "gray75"              
## [229] "gray76"               "gray77"               "gray78"              
## [232] "gray79"               "gray80"               "gray81"              
## [235] "gray82"               "gray83"               "gray84"              
## [238] "gray85"               "gray86"               "gray87"              
## [241] "gray88"               "gray89"               "gray90"              
## [244] "gray91"               "gray92"               "gray93"              
## [247] "gray94"               "gray95"               "gray96"              
## [250] "gray97"               "gray98"               "gray99"              
## [253] "gray100"              "green"                "green1"              
## [256] "green2"               "green3"               "green4"              
## [259] "greenyellow"          "grey"                 "grey0"               
## [262] "grey1"                "grey2"                "grey3"               
## [265] "grey4"                "grey5"                "grey6"               
## [268] "grey7"                "grey8"                "grey9"               
## [271] "grey10"               "grey11"               "grey12"              
## [274] "grey13"               "grey14"               "grey15"              
## [277] "grey16"               "grey17"               "grey18"              
## [280] "grey19"               "grey20"               "grey21"              
## [283] "grey22"               "grey23"               "grey24"              
## [286] "grey25"               "grey26"               "grey27"              
## [289] "grey28"               "grey29"               "grey30"              
## [292] "grey31"               "grey32"               "grey33"              
## [295] "grey34"               "grey35"               "grey36"              
## [298] "grey37"               "grey38"               "grey39"              
## [301] "grey40"               "grey41"               "grey42"              
## [304] "grey43"               "grey44"               "grey45"              
## [307] "grey46"               "grey47"               "grey48"              
## [310] "grey49"               "grey50"               "grey51"              
## [313] "grey52"               "grey53"               "grey54"              
## [316] "grey55"               "grey56"               "grey57"              
## [319] "grey58"               "grey59"               "grey60"              
## [322] "grey61"               "grey62"               "grey63"              
## [325] "grey64"               "grey65"               "grey66"              
## [328] "grey67"               "grey68"               "grey69"              
## [331] "grey70"               "grey71"               "grey72"              
## [334] "grey73"               "grey74"               "grey75"              
## [337] "grey76"               "grey77"               "grey78"              
## [340] "grey79"               "grey80"               "grey81"              
## [343] "grey82"               "grey83"               "grey84"              
## [346] "grey85"               "grey86"               "grey87"              
## [349] "grey88"               "grey89"               "grey90"              
## [352] "grey91"               "grey92"               "grey93"              
## [355] "grey94"               "grey95"               "grey96"              
## [358] "grey97"               "grey98"               "grey99"              
## [361] "grey100"              "honeydew"             "honeydew1"           
## [364] "honeydew2"            "honeydew3"            "honeydew4"           
## [367] "hotpink"              "hotpink1"             "hotpink2"            
## [370] "hotpink3"             "hotpink4"             "indianred"           
## [373] "indianred1"           "indianred2"           "indianred3"          
## [376] "indianred4"           "ivory"                "ivory1"              
## [379] "ivory2"               "ivory3"               "ivory4"              
## [382] "khaki"                "khaki1"               "khaki2"              
## [385] "khaki3"               "khaki4"               "lavender"            
## [388] "lavenderblush"        "lavenderblush1"       "lavenderblush2"      
## [391] "lavenderblush3"       "lavenderblush4"       "lawngreen"           
## [394] "lemonchiffon"         "lemonchiffon1"        "lemonchiffon2"       
## [397] "lemonchiffon3"        "lemonchiffon4"        "lightblue"           
## [400] "lightblue1"           "lightblue2"           "lightblue3"          
## [403] "lightblue4"           "lightcoral"           "lightcyan"           
## [406] "lightcyan1"           "lightcyan2"           "lightcyan3"          
## [409] "lightcyan4"           "lightgoldenrod"       "lightgoldenrod1"     
## [412] "lightgoldenrod2"      "lightgoldenrod3"      "lightgoldenrod4"     
## [415] "lightgoldenrodyellow" "lightgray"            "lightgreen"          
## [418] "lightgrey"            "lightpink"            "lightpink1"          
## [421] "lightpink2"           "lightpink3"           "lightpink4"          
## [424] "lightsalmon"          "lightsalmon1"         "lightsalmon2"        
## [427] "lightsalmon3"         "lightsalmon4"         "lightseagreen"       
## [430] "lightskyblue"         "lightskyblue1"        "lightskyblue2"       
## [433] "lightskyblue3"        "lightskyblue4"        "lightslateblue"      
## [436] "lightslategray"       "lightslategrey"       "lightsteelblue"      
## [439] "lightsteelblue1"      "lightsteelblue2"      "lightsteelblue3"     
## [442] "lightsteelblue4"      "lightyellow"          "lightyellow1"        
## [445] "lightyellow2"         "lightyellow3"         "lightyellow4"        
## [448] "limegreen"            "linen"                "magenta"             
## [451] "magenta1"             "magenta2"             "magenta3"            
## [454] "magenta4"             "maroon"               "maroon1"             
## [457] "maroon2"              "maroon3"              "maroon4"             
## [460] "mediumaquamarine"     "mediumblue"           "mediumorchid"        
## [463] "mediumorchid1"        "mediumorchid2"        "mediumorchid3"       
## [466] "mediumorchid4"        "mediumpurple"         "mediumpurple1"       
## [469] "mediumpurple2"        "mediumpurple3"        "mediumpurple4"       
## [472] "mediumseagreen"       "mediumslateblue"      "mediumspringgreen"   
## [475] "mediumturquoise"      "mediumvioletred"      "midnightblue"        
## [478] "mintcream"            "mistyrose"            "mistyrose1"          
## [481] "mistyrose2"           "mistyrose3"           "mistyrose4"          
## [484] "moccasin"             "navajowhite"          "navajowhite1"        
## [487] "navajowhite2"         "navajowhite3"         "navajowhite4"        
## [490] "navy"                 "navyblue"             "oldlace"             
## [493] "olivedrab"            "olivedrab1"           "olivedrab2"          
## [496] "olivedrab3"           "olivedrab4"           "orange"              
## [499] "orange1"              "orange2"              "orange3"             
## [502] "orange4"              "orangered"            "orangered1"          
## [505] "orangered2"           "orangered3"           "orangered4"          
## [508] "orchid"               "orchid1"              "orchid2"             
## [511] "orchid3"              "orchid4"              "palegoldenrod"       
## [514] "palegreen"            "palegreen1"           "palegreen2"          
## [517] "palegreen3"           "palegreen4"           "paleturquoise"       
## [520] "paleturquoise1"       "paleturquoise2"       "paleturquoise3"      
## [523] "paleturquoise4"       "palevioletred"        "palevioletred1"      
## [526] "palevioletred2"       "palevioletred3"       "palevioletred4"      
## [529] "papayawhip"           "peachpuff"            "peachpuff1"          
## [532] "peachpuff2"           "peachpuff3"           "peachpuff4"          
## [535] "peru"                 "pink"                 "pink1"               
## [538] "pink2"                "pink3"                "pink4"               
## [541] "plum"                 "plum1"                "plum2"               
## [544] "plum3"                "plum4"                "powderblue"          
## [547] "purple"               "purple1"              "purple2"             
## [550] "purple3"              "purple4"              "red"                 
## [553] "red1"                 "red2"                 "red3"                
## [556] "red4"                 "rosybrown"            "rosybrown1"          
## [559] "rosybrown2"           "rosybrown3"           "rosybrown4"          
## [562] "royalblue"            "royalblue1"           "royalblue2"          
## [565] "royalblue3"           "royalblue4"           "saddlebrown"         
## [568] "salmon"               "salmon1"              "salmon2"             
## [571] "salmon3"              "salmon4"              "sandybrown"          
## [574] "seagreen"             "seagreen1"            "seagreen2"           
## [577] "seagreen3"            "seagreen4"            "seashell"            
## [580] "seashell1"            "seashell2"            "seashell3"           
## [583] "seashell4"            "sienna"               "sienna1"             
## [586] "sienna2"              "sienna3"              "sienna4"             
## [589] "skyblue"              "skyblue1"             "skyblue2"            
## [592] "skyblue3"             "skyblue4"             "slateblue"           
## [595] "slateblue1"           "slateblue2"           "slateblue3"          
## [598] "slateblue4"           "slategray"            "slategray1"          
## [601] "slategray2"           "slategray3"           "slategray4"          
## [604] "slategrey"            "snow"                 "snow1"               
## [607] "snow2"                "snow3"                "snow4"               
## [610] "springgreen"          "springgreen1"         "springgreen2"        
## [613] "springgreen3"         "springgreen4"         "steelblue"           
## [616] "steelblue1"           "steelblue2"           "steelblue3"          
## [619] "steelblue4"           "tan"                  "tan1"                
## [622] "tan2"                 "tan3"                 "tan4"                
## [625] "thistle"              "thistle1"             "thistle2"            
## [628] "thistle3"             "thistle4"             "tomato"              
## [631] "tomato1"              "tomato2"              "tomato3"             
## [634] "tomato4"              "turquoise"            "turquoise1"          
## [637] "turquoise2"           "turquoise3"           "turquoise4"          
## [640] "violet"               "violetred"            "violetred1"          
## [643] "violetred2"           "violetred3"           "violetred4"          
## [646] "wheat"                "wheat1"               "wheat2"              
## [649] "wheat3"               "wheat4"               "whitesmoke"          
## [652] "yellow"               "yellow1"              "yellow2"             
## [655] "yellow3"              "yellow4"              "yellowgreen"

Third party: - RColorBrewer - Crayola Colours: https://en.wikipedia.org/wiki/List_of_Crayola_crayon_colors

Colour Ramps

Agian, these are custom colour continuums or Spectrums which gradually vary over a sequence of colours

Grey Colour Ramp

grey(x): a function which returns a grey colour based on the input argument in the range \(x\in[0,1]\)

N <- 30
x <- seq(0, 1, length.out = N)
pie(rep(1/N,N), labels = round(x, 2), col = gray(x))

Custom Pastel & Rainbow Ramps

To achieve soft, pale, and muted shades of an initial colour we can mix a single colour with white e.g. colorRamp(c(“white”,“blue”)) colourRamp is a functional which takes a vector of input colours (e.g. c(“blue”,) and returns a (vectorised) function which returns a softer colour based on the input in the range \(x\in[0,1]\).

bluePalette <- colorRamp(c("white","blue"))

# now I can sample from the palette to get RGB colours...
myRGBCustomWhite <- bluePalette(0.0)
myRGBLightBlue <- bluePalette(0.5)
myRGBVibrantBlue <- bluePalette(1.0)

# Convert RGB values to hex...
myHEXCustomWhite <- rgb(bluePalette(0.0) / 255)
myHEXLightBlue <- rgb(bluePalette(0.5) / 255)
myHEXVibrantBlue <- rgb(bluePalette(1.0) / 255)

likewise we can pass in a multi colour sequence to produce a colour ramp function which outputs a colour by interpolating along the sequence (palette) we input…

rainbowPalette <- colorRamp(c("red","orange","yellow","green","blue","violet"))

Colour Palettes

A set of colours containing/providing a fixed number of colours.

Pre-baked Palettes

RColourBrewer provides a number of pre-baked palettes split into:

  • sequential: for aesthetic mapping to a continuous variable perhaps?

  • diverging: palettes to create ramps or for directly feeding heatmaps, scatterplots, choropleths and the like

  • qualitative: for categorical data or whatever

library(RColorBrewer)
display.brewer.all()

You can fetch a bunch of colours to feed directly into a plotting command as a colour argument, notice that if we exceed the number of colours in the original palette the colours are reused leading it issues.

# Example: Get a set of 12 colours in the "Accent" palette
myAccentColourScheme <- brewer.pal(12, "Accent")
## Warning in brewer.pal(12, "Accent"): n too large, allowed maximum for palette Accent is 8
## Returning the palette you asked for with that many colors
pie(
  rep(1/12,12),
  col = myAccentColourScheme
)

A better use of these colour scheme is as a seed for a custom colour palette.

myAccentColourScheme <- brewer.pal(6, "Accent")
myAccentPalette <- colorRamp(myAccentColourScheme)

pie(
  rep(1/16,16),
  col = rgb(myAccentPalette(seq(0, 1, length.out = 16))/255)
)

Custom Palettes

The functional colorRampPalette() takes a color palette and returns another palette generation function. The palette generation function takes and integer \(N\) and outputs a palette of \(N\) corresponding colours by interpolating the original input palette.

All this machinery looks overly sophisticated but it’s handy or needed for feeding color arguments in calls to plotting functions

my5ColourPalette<-colorRampPalette(c("red", "green","blue"))(5)
my50ColourPalette<-colorRampPalette(c("red", "green","blue"))(50)

Alpha

a sure way to set transparency for a colout is through the rgb function or adjustcolor.

# instantiate translucent color
myTranslucentRed1 <- rgb(
  red=1,
  green=0,
  blue=0,
  alpha=0.5
)

# set RGB transparency
myTranslucentRed2 <- rgb(colorRamp("blue")(0)/255)

# set HEX transparency
myTranslucentRed3 <- adjustcolor("#FF0000", alpha.f = 0.5)

Primary Colours

The visible spectrum is one-dimensional, spanning a range of wavelengths from approximately 400 nm (violet) to 700 nm (red). However, human color vision is trichromatic, meaning it relies on three types of photoreceptor cells in the retina, called cones, which are sensitive to different parts of the spectrum in well-lit conditions. These cones are:

  • L-cones (Long wavelength): Most sensitive to low-frequency, reddish light.
  • M-cones (Medium wavelength): Most sensitive to medium-frequency, greenish light.
  • S-cones (Short wavelength): Most sensitive to high-frequency, bluish light.

The brain processes the signals from these three cone types to perceive color, allowing us to distinguish millions of colors through additive mixing. This trichromatic nature underpins why we use Red, Green, and Blue (RGB) as the primary colors for additive color mixing (e.g., in screens and digital displays). In contrast, the Red, Yellow, and Blue (RYB) model is used in subtractive color mixing (e.g., with pigments or paints). In this model, colors are perceived based on which wavelengths are absorbed versus reflected. Each pigment absorbs light at specific wavelengths:

  • Red absorbs short wavelengths (blue/violet).
  • Yellow absorbs medium wavelengths (green).
  • Blue absorbs long wavelengths (red).

While RYB works for traditional artistic color mixing, modern color science often uses Cyan, Magenta, and Yellow (CMY) as the subtractive primaries due to their more precise alignment with the physics of light absorption and reflection.

Some humans have an additional color sensor in the mid-range (tetrachromatic), enabling them to perceive yellows and greens with much greater distinction. In contrast, dogs are dichromatic and lack the ability to sense colors in the yellow/green wavelengths, limiting their color vision.

Mantis shrimps, however, are extraordinary in this regard, possessing 16 different types of photoreceptors. This gives them:

  • A more vivid color palette: With more photoreceptors in the visible spectrum, they can differentiate hues that are indistinguishable to humans.
  • A broader range of visible colors: They can see into parts of the infrared (IR) and ultraviolet (UV) spectrum that are invisible to humans.
  • Light polarization sensitivity: This unique ability adds an extra “dimension” to their vision, allowing them to detect the orientation and filtering of light waves.

Wetware in the brain mstill means that we get a richer colour ramp using a palette of Red, orange,yellow,green,blue,indego and violet compared to one of only red, green and blue

While it’s true that the three primary colors—red, green, and blue (RGB)—can theoretically stimulate all three types of photoreceptors (cones) in the human eye, the reason a ROYGBIV ramp (red, orange, yellow, green, blue, indigo, violet) looks richer and more nuanced than an RGB ramp lies in the nature of how colors are mixed, perceived, and displayed. Here’s why:

  1. Human Perception of Color and Gradients Human color perception isn’t just about stimulating cones (L, M, S for long, medium, and short wavelengths corresponding to red, green, and blue). Our perception of color is highly influenced by the relative proportions of stimulation from all three cones and how the brain interprets those signals. A color ramp using ROYGBIV has smoother transitions between colors, mimicking the natural spectrum of light seen in a rainbow. These transitions align more closely with how our visual system processes continuous changes in wavelength. On the other hand, when mixing just red, green, and blue, there are fewer intermediate colors, and the transitions between hues can appear more abrupt, leading to a less “rich” gradient.
  2. Spectral Colors vs. Additive RGB Colors ROYGBIV represents spectral colors, which are pure wavelengths of light in the visible spectrum (e.g., red at ~700 nm, violet at ~400 nm). These colors stimulate our cones in a way that feels natural because they correspond to how light behaves physically. RGB, on the other hand, is an additive color model used in digital displays. It creates colors by mixing light from red, green, and blue channels, but it does so using discrete values and does not replicate the smooth transitions of a spectrum. Many colors in the spectrum (e.g., cyan, yellow) are approximated by blends of RGB primaries, which are not pure spectral colors.
  3. Intermediate Colors and Cone Response Intermediate colors like orange, yellow, and cyan (found in ROYGBIV) are blends of light wavelengths that stimulate cones in a way that is closer to natural perception. For example: Yellow stimulates both the red (L) and green (M) cones strongly, creating a distinct perceptual response that feels different from simply blending red and green in RGB. Similarly, orange provides a softer transition from red to yellow, which feels more intuitive and natural. With just red, green, and blue, it’s harder to hit the exact combinations of cone stimulation that mimic intermediate colors like yellow, orange, and cyan because these colors have to be created by approximation in RGB.
  4. Color Models and Gamut The RGB model has a limited gamut (range of colors it can produce) compared to the full spectrum of colors perceivable by the human eye. Even though RGB can create many colors by mixing, it cannot perfectly replicate spectral colors like pure yellow or violet. The ROYGBIV ramp inherently uses more points in the visible spectrum, so it better approximates the way light naturally stimulates our cones across the rainbow.
  5. Psychological Effects of Gradients A smooth ROYGBIV ramp is more visually satisfying because it replicates what we see in natural phenomena like rainbows or sunlight passing through a prism. This aligns with the expectations of our visual system, making it feel richer. In contrast, an RGB ramp can feel more artificial because it moves between three extremes (red, green, and blue) without accounting for the intermediate hues our eyes expect.
  6. Implementation in R When creating a color ramp in R, the function you use (e.g., colorRampPalette()) interpolates between the colors you provide. If you supply only red, green, and blue, the interpolation will move linearly between these three points in RGB space, skipping intermediate hues like orange or cyan. By including ROYGBIV, you’re explicitly telling R to include more “stopping points” in the gradient, which ensures that the ramp passes through intermediate colors. This makes the gradient smoother and feels more natural to our eyes.
  7. Why Not Just RGB? While RGB stimulates all three cones, it doesn’t account for how humans interpret blends of color. The color-processing centers in our brains expect natural transitions between colors based on their physical wavelengths. A gradient built only from red, green, and blue doesn’t provide enough resolution or intermediate steps to match that natural perception. The ROYGBIV palette bridges this gap by incorporating colors that approximate these intermediate steps, even if they aren’t perfect spectral colors.