On Tue, Oct 13, 2009 at 9:43 PM, Bryan Hanson <han...@depauw.edu> wrote: > Hello List Dwellers: > > I¹ve looked around quite a bit, but don¹t quite see an answer that I > understand. > > I¹m looking for a way to take any kind of color specification (rgb, hsv, > hcl, hex) and match it to the n-nearest R official color names. Clearly it > is easy to interconvert different specification schemes and color spaces, > but matching to the name seems a bit trickier. Seems like if one has a > specification, it could be fuzzy-matched to the list of official R colors > expressed in the same specification. Unfortunately, I don¹t know much about > fuzzy matching. > > For example, following some examples I found in the archives and the wiki, I > wrote this little function to create a table of official R colors and sort > it if desired: > > colorSpecTable <- function(col = colors(), sort = NULL){ > require(gplots) > rgbcodes <- t(col2rgb(col)) > names <- col > hex <- col2hex(col) > df <- data.frame(name = names, hex.code = hex, rgbcodes) > # additional elements for other color spaces could be added > if (!identical(sort, NULL)) df <- sort.data.frame(df, by = sort) > } > > Note that sort.data.frame is from the R-wiki and is appended below. Is > there a clever way to search a table created by this function, and identify > the n-closest colors based upon some reasonable criteria? What I hope for > is something like this: > > colorMatch <- function(hex = NULL, n, plot = HOPEFULLY) { > df.rgb <- colorSpecTable(sort = ~red+green+blue) # master table > # now search for the n closest matches of hex in df.rgb$hex.code > # perhaps hex should be converted into a different color space 1st > # eventually would like to display matches side by side w/hex > }
You just need to define your distance in colour space. Simplest might be a euclidean distance in three-dimensional r,g,b coordinates, something like: nearColour <- function(r,g,b){ ctable = col2rgb(colors()) cdiff = ctable - c(r,g,b) cdist = cdiff[1,]*cdiff[1,]+cdiff[2,]*cdiff[2,]+cdiff[3,]*cdiff[3,] return(colors()[cdist == min(cdist)]) } This gives colour names nearest to r,g,b triples, with possible multiple results: > nearColour(0,0,0) [1] "black" "gray0" "grey0" > nearColour(1,1,1) [1] "black" "gray0" "grey0" > nearColour(255,255,255) [1] "white" "gray100" "grey100" > nearColour(128,0,0) [1] "darkred" "red4" Any good? You could also do it in hsv space, but there's probably enough colours in the colors() vector that it wouldn't make much difference... Barry ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.