Grokbase Groups R r-help October 2009
FAQ
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
}

Thanks as always. Bryan
*************
Bryan Hanson
Acting Chair
Professor of Chemistry & Biochemistry
DePauw University, Greencastle IN USA

sort.data.frame <- function(x, by){
# Author: Kevin Wright
# with some ideas from Andy Liaw
# Found in the R Wiki

# x: A data.frame
# by: A one-sided formula using + for ascending and - for descending
# Sorting is left to right in the formula

# Useage is:
# library(nlme);
# data(Oats)
# sort(Oats, by= ~nitro-Variety)

if(by[[1]] != "~")
stop("Argument 'by' must be a one-sided formula.")

# Make the formula into character and remove spaces
formc <- as.character(by[2])
formc <- gsub(" ", "", formc)
# If the first character is not + or -, add +
if(!is.element(substring(formc, 1, 1), c("+", "-")))
formc <- paste("+", formc, sep = "")

# Extract the variables from the formula
vars <- unlist(strsplit(formc, "[\\+\\-]"))
vars <- vars[vars != ""] # Remove any extra "" terms

# Build a list of arguments to pass to "order" function
calllist <- list()
pos <- 1 # Position of + or -
for(i in 1:length(vars)){
varsign <- substring(formc, pos, pos)
pos <- pos + 1 + nchar(vars[i])
if(is.factor(x[, vars[i]])){
if(varsign == "-") {
calllist[[i]] <- -rank(x[, vars[i]])
} else {
calllist[[i]] <- rank(x[, vars[i]])
}
} else {
if(varsign == "-") {
calllist[[i]] <- -x[, vars[i]]
} else {
calllist[[i]] <- x[,vars[i]]
}
}
}
return(x[do.call("order", calllist), ])
}

Search Discussions

  • Barry Rowlingson at Oct 13, 2009 at 9:12 pm

    On Tue, Oct 13, 2009 at 9:43 PM, Bryan Hanson 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
  • Bryan Hanson at Oct 13, 2009 at 9:58 pm
    Works perfectly! Thanks Barry. I had actually seen some suggestions on
    using a distance, but by then I was thinking about hcl spaces and distance
    isn't so as simple there. I'm too tired I think.

    Anyway, you've got me running again! Thanks, Bryan

    On 10/13/09 5:12 PM, "Barry Rowlingson" wrote:
    On Tue, Oct 13, 2009 at 9:43 PM, Bryan Hanson 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
  • Barry Rowlingson at Oct 13, 2009 at 10:05 pm

    On Tue, Oct 13, 2009 at 10:58 PM, Bryan Hanson wrote:
    Works perfectly! ?Thanks Barry. ?I had actually seen some suggestions on
    using a distance, but by then I was thinking about hcl spaces and distance
    isn't so as simple there. ?I'm too tired I think.

    Anyway, you've got me running again! ?Thanks, Bryan
    There's a CPAN module for Perl that does hcl colour similarity:
    http://search.cpan.org/~mbarbon/Color-Similarity-HCL-0.04/lib/Color/Similarity/HCL.pm
    the Perl code is pretty neat, looks easy to R-ify - released under
    the perl license.

    Barry
  • Romain Francois at Oct 14, 2009 at 10:26 am

    On 10/14/2009 12:05 AM, Barry Rowlingson wrote:
    On Tue, Oct 13, 2009 at 10:58 PM, Bryan Hansonwrote:
    Works perfectly! Thanks Barry. I had actually seen some suggestions on
    using a distance, but by then I was thinking about hcl spaces and distance
    isn't so as simple there. I'm too tired I think.

    Anyway, you've got me running again! Thanks, Bryan
    There's a CPAN module for Perl that does hcl colour similarity:
    http://search.cpan.org/~mbarbon/Color-Similarity-HCL-0.04/lib/Color/Similarity/HCL.pm
    the Perl code is pretty neat, looks easy to R-ify - released under
    the perl license.

    Barry
    There are a few unexported functions in the xterm256 package to deal
    with this.
    colors()[ xterm256:::closest.character( "#aabbcc" ) ]
    [1] "gold4"

    The package pretends it writes the text using the background of
    foreground color as usually represented in R, but it actually first
    grabs the closest color (in the RGB space according to the euclidian
    metric, I have no idea whether a different space or a different metric
    would be better)

    This presentation might give a clue :
    http://www.agrocampus-ouest.fr/math/useR-2009//slides/Zeileis+Hornik+Murrell.pdf

    Romain

    --
    Romain Francois
    Professional R Enthusiast
    +33(0) 6 28 91 30 30
    http://romainfrancois.blog.free.fr
    - http://tr.im/BcPw : celebrating R commit #50000
    - http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
    `- http://tr.im/yw8E : New R package : sos
  • Romain Francois at Oct 14, 2009 at 11:22 am

    On 10/14/2009 12:26 PM, Romain Francois wrote:
    On 10/14/2009 12:05 AM, Barry Rowlingson wrote:

    On Tue, Oct 13, 2009 at 10:58 PM, Bryan Hansonwrote:
    Works perfectly! Thanks Barry. I had actually seen some suggestions on
    using a distance, but by then I was thinking about hcl spaces and
    distance
    isn't so as simple there. I'm too tired I think.

    Anyway, you've got me running again! Thanks, Bryan
    There's a CPAN module for Perl that does hcl colour similarity:
    http://search.cpan.org/~mbarbon/Color-Similarity-HCL-0.04/lib/Color/Similarity/HCL.pm

    the Perl code is pretty neat, looks easy to R-ify - released under
    the perl license.

    Barry
    There are a few unexported functions in the xterm256 package to deal
    with this.
    colors()[ xterm256:::closest.character( "#aabbcc" ) ]
    [1] "gold4"
    Actually that is wrong closest.character gives you the index of the
    closest xterm256 color, as in : http://frexx.de/xterm-256-notes/

    sorry for the misleading answer ...
    The package pretends it writes the text using the background of
    foreground color as usually represented in R, but it actually first
    grabs the closest color (in the RGB space according to the euclidian
    metric, I have no idea whether a different space or a different metric
    would be better)

    This presentation might give a clue :
    http://www.agrocampus-ouest.fr/math/useR-2009//slides/Zeileis+Hornik+Murrell.pdf


    Romain

    --
    Romain Francois
    Professional R Enthusiast
    +33(0) 6 28 91 30 30
    http://romainfrancois.blog.free.fr
    - http://tr.im/BcPw : celebrating R commit #50000
    - http://tr.im/ztCu : RGG #158:161: examples of package IDPmisc
    `- http://tr.im/yw8E : New R package : sos
  • Jim Lemon at Oct 14, 2009 at 10:15 am
    Hi Bryan,
    You can get a near match with the color.id function in the plotrix package.

    Jim

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupr-help @
categoriesr
postedOct 13, '09 at 8:43p
activeOct 14, '09 at 11:22a
posts7
users4
websiter-project.org
irc#r

People

Translate

site design / logo © 2022 Grokbase