问题
Update (Original question below)
Issue is partially solved.
Still trying to figure out how to extend to other color combinations
If I use this code
hLIM <- rgb2hsv(col2rgb('#8000ff'))['h', ]
sLIM <- rgb2hsv(col2rgb('#8000ff'))['s', ]
vLIM <- rgb2hsv(col2rgb('#8000ff'))['v', ]
rankorder <- order((hLIM-tHSVcol[,1] + (hLIM < tHSVcol[,1])),
(sLIM-tHSVcol[,2] + (sLIM < tHSVcol[,2])),
(vLIM-tHSVcol[,3] + (vLIM < tHSVcol[,3])))
orderType <- "HSV Ordering"
I am able to sort this
Unsorted Color Palette:
"#313695","#fdae61","#a50026","#ffffbf","#f46d43","#fee090","#e0f3f8","#74add1","#d73027","#4575b4","#abd9e9"
Into this
Sorted Color Palette:
"#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1", "#4575b4","#313695"
However, I have difficulty extending it to other color combinations.
For Instance when I try to sort this
Unsorted
"#22325f" "#88ce64" "#fbd234" "#b8091f" "#682f4e" "#fdea6e" "#4aec6a" "#fb7894" "#f13111" "#2584a0" "#460809" "#00699e" "#391b72" "#03471d" "#ba0841"
I get this (Interesting part is, I'm unsure how the perfectly sorted palette would look like ---- certainly no dark bands interspersed!)
Imperfectly Sorted
"#391b72" "#22325f" "#00699e" "#2584a0" "#03471d" "#4aec6a" "#88ce64" "#fdea6e" "#fbd234" "#f13111" "#460809" "#b8091f" "#fb7894" "#ba0841" "#682f4e"
Original Question
I have a finite palette, how to sort from Hot(reds) to Cold(blues).
How do I turn this
Unsorted Color Palette:
"#313695","#fdae61","#a50026","#ffffbf","#f46d43","#fee090","#e0f3f8","#74add1","#d73027","#4575b4","#abd9e9"
Into this
Sorted Color Palette:
"#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1", "#4575b4","#313695"
R Code is at the end of the message. I tried sorting by combinations of RGB
and HSV
, (based on what is commented, or uncommented) but to no avail.
I am unable to find a pattern in the following values (where colors are sorted divergently)
Any guidance is greatly appreciated.
RGB Sorted Color
> tRGBcol
red green blue
[1,] 165 0 38
[2,] 215 48 39
[3,] 244 109 67
[4,] 253 174 97
[5,] 254 224 144
[6,] 255 255 191
[7,] 224 243 248
[8,] 171 217 233
[9,] 116 173 209
[10,] 69 117 180
[11,] 49 54 149
HSV Sorted Color
> tHSVcol
h s v
[1,] 0.961616162 1.00000000 0.6470588
[2,] 0.008522727 0.81860465 0.8431373
[3,] 0.039548023 0.72540984 0.9568627
[4,] 0.082264957 0.61660079 0.9921569
[5,] 0.121212121 0.43307087 0.9960784
[6,] 0.166666667 0.25098039 1.0000000
[7,] 0.534722222 0.09677419 0.9725490
[8,] 0.543010753 0.26609442 0.9137255
[9,] 0.564516129 0.44497608 0.8196078
[10,] 0.594594595 0.61666667 0.7058824
[11,] 0.658333333 0.67114094 0.5843137
Manually split hex colors
a5 00 26
d7 30 27
f4 6d 43
fd ae 61
fe e0 90
ff ff bf
e0 f3 f8
ab d9 e9
74 ad d1
45 75 b4
31 36 95
Code
RenderPal <- function(x,name){
if ((missing(x)) || (missing(name))){
stop("Internal error, please troubleshoot")
}
n <- length(x)
old <- graphics::par(mar = c(0.5, 0.5, 0.5, 0.5))
on.exit(graphics::par(old))
graphics::image(1:n, 1, as.matrix(1:n), col = x,
ylab = "", xaxt = "n", yaxt = "n", bty = "n")
graphics::rect(0, 0.9, n + 1, 1.1, col = grDevices::rgb(1, 1, 1, 0.8), border = NA)
graphics::text((n + 1) / 2, 1, labels = name, cex = 2, family = "serif")
}
i <- NULL
oldPal <- NULL
rankorder <- c(1,2,3,4,5,6,7,8,9,10,11)
orderedPal<- NULL
RGBcol <- NULL
HSVcol <- NULL
tHSVcol <- NULL
orderType <- "Unsorted"
oldPal <- c("#313695","#fdae61","#a50026","#ffffbf","#f46d43","#fee090","#e0f3f8","#74add1","#d73027","#4575b4","#abd9e9")
# Print hex values
oldPal
# Convert Hex to RGB
RGBcol <- col2rgb(oldPal)
# Print RGB values
RGBcol
# Transpose matrix
tRGBcol <- t(RGBcol)
# Print matrix
tRGBcol
# Uncomment following to order by Red, Green, then Blue
# rankorder <- order(tRGBcol[,1],tRGBcol[,2],tRGBcol[,3])
# orderType <- "Red Ordering"
# Uncomment following to order by Blue, Green, then Red
# rankorder <- order(tRGBcol[,3],tRGBcol[,2],tRGBcol[,1])
# orderType <- "Blue Ordering"
# Uncomment following to order by Green, Blue then Red
# rankorder <- order(tRGBcol[,2],tRGBcol[,3],tRGBcol[,1])
# orderType <- "Green Ordering"
# Uncomment following to order by Red + Blue
# rANDb <- apply(tRGBcol[,c(1,3)],1,sum)
# rankorder <- order(rANDb)
# orderType <- "Red + Blue Ordering"
# Uncomment following to order by Red + Green + Blue
# rANDgANDb <- apply(tRGBcol[,c(1,2,3)],1,sum)
# rankorder <- order(rANDgANDb)
# orderType <- "Red + Green + Blue Ordering"
# Convert RGB to HSV
HSVcol <- rgb2hsv(RGBcol)
# Print matrix
HSVcol
# Transpose matrix
tHSVcol <- t(HSVcol)
# Print matrix
tHSVcol
# Uncomment following to order by Hue, then Saturation, then Value
# rankorder <- order(tHSVcol[,1],tHSVcol[,2],tHSVcol[,3])
# orderType <- "Hue Ordering"
# Uncomment following to order by hANDv = Hue + Value
# hANDv <- apply(tHSVcol[,c(1,3)],1,sum)
# rankorder <- order(hANDv)
# orderType <- "Hue + Value Ordering"
# Uncomment following to order by hPRODv = Hue * Value
# hPRODv <- apply(tHSVcol[,c(1,3)],1,prod)
# rankorder <- order(hPRODv)
# orderType <- "Hue * Value Ordering"
# Combine matrices tRGBcol and tHSVcol
tCombo <- cbind(tRGBcol,tHSVcol)
rankorder
for (i in 1:length(rankorder)){
orderedPal[i] <- oldPal[rankorder[i]]
}
# Print old, unordered palette
oldPal
# Print new, ordered palette
orderedPal
RenderPal(oldPal, "Unordered Palette")
RenderPal(orderedPal, orderType)
Edit: Result when I sort by Hue
回答1:
I get almost your requested order with this:
Coolness = function(P) {
RGB = col2rgb(P)
(RGB[3,] - RGB[1,]) / (RGB[3,] + RGB[1,])
}
CoolPal = oldPal[order(Coolness(oldPal))]
RenderPal(CoolPal, "Coolness")
But notice that I have swapped the first two colors. Your suggested answer says that "#a50026" is hotter than "#d73027". My Coolness function has the opposite ordering for those two.
来源:https://stackoverflow.com/questions/51158179/given-a-finite-palette-how-to-sort-from-hot-to-cold-i-e-diverging