Randomly generate 3 different colors

I've looked over this one but doesn't help with the random part. Is there a better way to randomly generate 3 different colors so that the square, circle and text appear visually apart in the code below. The colors should be randomly generated and also sufficiently distinct from each other. The current code only works maybe half the time

plot(0, type = "n", xlim = c(0,10), ylim = c(0,10),
    ann = FALSE, axes = FALSE, asp = 1)

cols = colorRampPalette(sample(2:9,2), alpha = TRUE)(8)

polygon(x = c(1,9,9,1), y = c(1,1,9,9), border = NA, col = cols[1])

symbols(x = 5, y = 5, circles = 4, inches = FALSE,
    add = TRUE, bg = cols[4], fg = NA)

text(x = 5, y = 5, labels = "Hi", col = cols[7], font = 2, cex = 3)

      

Examples of

WELL

enter image description here

POLYGON: "# FF00FFFF", CIRCLE: "# 916DFFFF", TEXT: "# 24DAFFFF"

BAD

enter image description here

POLYGON: "# 00FFFFFF", CIRCLE: "# 51E3E3FF", TEXT: "# A2C7C7FF"

+3


source to share


2 answers


Updated answer

My original answer, which uses color space hcl

, often generated color combinations that are difficult to distinguish. This updated answer uses the Lab color space, which scales based on the perceptual distance between colors, so similar distances in laboratory space should correspond to similar perceived color differences. In Lab, L is the brightness or luminance on a scale of 0 to 100. a represents green to red and b represents blue to yellow, both on a scale of -100 to 100.

The code below generates two random values ​​for a

and b

. If we consider these two values ​​as representing a point in a plane ab

, we will create two more colors with maximum perceptual distance from each other by rotating this point first 120 degrees and then 240 degrees. We then select one L value to give us three equally spaced colors.

Below I have packed this into a function to make it easier to create multiple graphs with random colors. I also set a minimum absolute value for a and b so that we don't get too similar colors and include an argument Lval

to select the L value of the Lab colors.

Based on multiple runs, it looks like this approach works much better than my original hcl version (although this may be due not only to using lab space instead of hcl space, but also because I only used one hcl dimension but two dimensions laboratory space).

library(colorspace)

random.colors = function(Lval=80, ABmin=50) {

  # 120 deg rotation matrix
  aa = 2*pi/3
  rot = matrix(c(cos(aa), -sin(aa), sin(aa), cos(aa)), nrow=2, byrow=TRUE)

  # Generate random A and B points in LAB space
  x = runif(2, ABmin, 100) * sample(c(-1,1), 2,replace=TRUE) 

  # Create three equally spaced colors in Lab space and convert to RGB
  cols = LAB(cbind(rep(Lval,3), rbind(x, x %*% rot, x %*% rot %*% rot)))
  cols = rgb(convertColor(cols@coords, from="Lab", to="sRGB"))

  plot(0, type = "n", xlim = c(0,10), ylim = c(0,10),
       ann = FALSE, axes = FALSE, asp = 1)

  polygon(x = c(1,9,9,1), y = c(1,1,9,9), border = NA, col = cols[1])

  symbols(x = 5, y = 5, circles = 4, inches = FALSE,
          add = TRUE, bg = cols[2], fg = NA)

  text(x = 5, y = 5, labels = "Hi", col = cols[3], font = 2, cex = 3)
}

par(mfrow=c(3,3), mar=rep(0,4))
replicate(9,random.colors())  

      

enter image description here



For simplicity, the above example constrains the a and b values ​​to a constant distance from the origin (in ab-space) and uses the same L value for all three colors. Instead, you can extend this method to use all three dimensions of Lab space. Alternatively, instead of requiring a constant distance from the origin, you can choose the first color at random and then require the next two colors to be selected so that all three colors are separated as much as possible from each other in laboratory space.

Original Answer

You can create colors that are evenly spaced (that is, they have the greatest possible separation of shades from each other). For example:

set.seed(60)
cols = hcl(runif(1,0,359.99) + c(0,120,240), 100, 65)

plot(0, type = "n", xlim = c(0,10), ylim = c(0,10),
     ann = FALSE, axes = FALSE, asp = 1)

polygon(x = c(1,9,9,1), y = c(1,1,9,9), border = NA, col = cols[1])

symbols(x = 5, y = 5, circles = 4, inches = FALSE,
        add = TRUE, bg = cols[2], fg = NA)

text(x = 5, y = 5, labels = "Hi", col = cols[3], font = 2, cex = 3)

      

enter image description here

Here are nine more random draws. As you can see, there are several combinations that don't work very well. But perhaps you can play around with different ways of slicing the color space to see if you can improve something.

enter image description here

+4


source


One of the simplest ways is to sample from eight "standard" colors.

par(mar=c(0, 0, 0, 0))
set.seed(1)
plot(0, type = "n", xlim = c(0,10), ylim = c(0,10),
    ann = FALSE, axes = FALSE, asp = 1)

cols <- sample(2:8, 3)

polygon(x = c(1,9,9,1), y = c(1,1,9,9), border = NA, col = cols[1])

symbols(x = 5, y = 5, circles = 4, inches = FALSE,
    add = TRUE, bg = cols[2], fg = NA)

text(x = 5, y = 5, labels = "Hi", col = cols[3], font = 2, cex = 3)

      



enter image description here

+2


source







All Articles