http://qs321.pair.com?node_id=838805

shoness has asked for the wisdom of the Perl Monks concerning the following question:

Suppose I have a linear integer scale with GREEN assigned to the uppermost scale value and RED to the lowest scale value. YELLOW is assigned to the median scale value. (Like a traffic light that uses HTML color codes.)

If my scale is from 0 to 2, my color choices are easy.

When I have a larger scale, then it's more difficult. For instance, if my scale is from 0 to 10.

It's worse when the scale goes from 0 to 100?

There must be a CPAN module to help choose these (web-safe) colors, but I can't find one via searching...
Color::Calc::WWW
Color::Library::Color

Thanks for your help!

/Go Sharks!

Replies are listed 'Best First'.
Re: CPAN Module for Normalizing to Green-Yellow-Red Color Scheme?
by BrowserUk (Patriarch) on May 06, 2010 at 23:35 UTC
Re: CPAN Module for Normalizing to Green-Yellow-Red Color Scheme?
by ww (Archbishop) on May 07, 2010 at 00:07 UTC
    At least for this US reader, you have your traffic light upside down.

    ;-)

    But, more seriously, you could make your life easier if you used Red-Greeen-Blue for your range. Red-Yellow-Green just doesn't work even for your range of 10 possibilities; never mind for 100 (and certainly not for 100 distinguishable, web-safe colors.

    You may find some useful ideas (albeit, neither modules nor even code snippets) at this academic (UIUC) site. In addition, Wikipedia has an interesting item on color theory, including this which is particularly relevant to your question, identifying as a "problem"...

    ... the tendency to describe color effects holistically or categorically, for example as a contrast between "yellow" and "blue" conceived as generic colors, when most color effects are due to contrasts on three relative attributes that define all colors:

    1. lightness (light vs. dark, or white vs. black),
    2. saturation (intense vs. dull), and
    3. hue (e.g., red, orange, yellow, green, blue or purple).

    Thus, the visual impact of "yellow" vs. "blue" hues in visual design depends on the relative lightness and intensity of the hues.

    Update: Fixed the (badly borked) markup.

Re: CPAN Module for Normalizing to Green-Yellow-Red Color Scheme?
by duelafn (Parson) on May 07, 2010 at 00:38 UTC

    Update: D'oh, I missed the "Websafe" requirement (people still worry about that?) -- Feel free to ignore me...

    I have code which does this using Color::Calc.

    # Example usage: say for colors(distribute => 1, format=> "hex", n => 10, colors => [qw +/red yellow green/]); =head3 colors At the most basic level, converts colors to different formats, however + this subroutine is capable of quite a bit more than that. Examples: colors [qw/red green blue/], format => "ps"; colors [qw/red green blue/], format => "ps", n => 2; =over 4 =item colors A list of colors, can be an X11 color name or any of the other formats recognised by Color::Calc. =item n Only return n colors. =item interpolate If false, requesting more colors than available in the colors list wil +l throw a fatal error. The default is to create new colors between the g +iven colors if there are insufficient colors provided. The interpolate comm +and will also cause colors to be interpolated if the distribute option is +set. =item distribute By default, if fewer colors are requested than are contained in the co +lors list, this subroutine will select the first n colors. Providing a true value for distribute will cause the subroutine to evenly spread out th +e choice of colors over the range of colors provided (if n E<gt> 2 then +the first and last colors are guaranteed to be included). =item format Specify the style of the returned colors. Can be anything supported by Color::Calc which is currently (Color::Calc::VERSION == 1.0): "tuple", "hex", "html", "object" (a Graphics::ColorObject object), "pdf". The default format is "object". The following formats are also accepted and are handled by this subrou +tine directly: "ps" | "postscript". =item background Try to make the colors appear on the given background color. Colors B< +will> be altered if this option is provided. =back =cut #BEGIN: colors sub colors { require Color::Calc; unshift @_, "colors" if @_ % 2; my %o = @_; my $c = $o{colors}; my $n = $o{n} ||= @$c; $o{interpolate} = 1 unless exists $o{interpolate}; croak "Not enough "."colors in plot color database" unless $o{interp +olate} or $n <= @$c; $o{format} ||= 'object'; $o{format} = lc $o{format}; @o{qw/format _format/} = qw/tuple ps/ if $o{format} =~ /^(?:ps|posts +cript)$/; my $cct = Color::Calc->new( 'ColorScheme' => 'X', OutputFormat => 't +uple' ); my $cc = Color::Calc->new( 'ColorScheme' => 'X', OutputFormat => $o +{format} ); $o{listed} = 1 if $o{format} eq 'tuple'; if (($n > @$c) or ($o{distribute} and $o{interpolate})) { $c = [map [($_==int($_))?$$c[$_]:$cct->mix($$c[int $_],$$c[int($_) ++1], $_-int($_))], map +($_*($#{$c})/(($n-1)||1)), 0..$n-1]; } elsif ($o{distribute} and $n < @$c) { $c = [map $$c[int($_*($#{$c})/(($n-1)||1))], 0..$n-1]; } if ($o{background}) { my $fg = $cc->contrast_bw($o{background}); if ($o{listed}) { $c = [ map [$cc->mix($_, $fg, .35)], @$c[0..$n-1] ]; } else { $c = [ map $cc->mix($_, $fg, .35), @$c[0..$n-1] ]; } } else { if ($o{listed}) { $c = [ map [$cc->get($_)], @$c[0..$n-1] ]; } else { $c = [ map $cc->get($_), @$c[0..$n-1] ]; } } if ($o{_format}) { $o{_format} eq 'ps' and do { for (@$c) { $_ /= 255 for @$_ } }; } return wantarray ? @$c : $c; } #END: colors

    Good Day,
        Dean