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

Hi,

I'm trying to write a score function.
The score function is applied to each cell of a grid
and because the grid has many cells ( 400x600 or 800x600 )
If I want to experiment with different score functions to
see which one is best I'd have to see some kind of visual results.
I thought of plotting that score function to the screen
(because viewing just numbers isn't enough any more)
and all it's values will be colors of pixels on a grid.
The problem is choosing the colors and the transition between low-values to
big values of the score function so that they show up as beeing relevant
and smooth to the eye.
Let's take euclidean distance as the score function for example.
If we have 2 objects,one fixed at the bottom right of the screen and one
starting in the upper left and moving towards upper right,then a transition of colors should
be made for the area where the fixed object is , and the signification of this will be
that the distance between these objects is getting smaller and smaller.
I have tried getting the euclidean distance normalized to fit in the color spectrum and then
plotting but that turns out to not be so good either.
I'm having difficulties finding the best mapping between colors->distance.

Has anyone tried this ?

Thank you

Replies are listed 'Best First'.
Re: Mapping function values to colors
by BrowserUk (Patriarch) on Dec 10, 2008 at 00:45 UTC
      Hi BrowserUK,thanks allot,that really helped,I was able to get some quick results.
      However,I will be concerned about the granularity of this,and also,because my values have a peak of 485 now, it's all shown in a blue nuances.
      But soon I will probably have higher values , maybe 1000,maybe 10000 ...
      it's not as easy as I thought(looking on your code) to deal with those high numbers as well.
      I will look more into your code and the color ramping link http://local.wasp.uwa.edu.au/~pbourke/texture_colour/colourramp/
      was excellent, thank you :)

      P.S. : perlmonks seems to always be full of knowledgeble people , of all the places I'd ask,I didn't expect
      the answer would come from here
        However,I will be concerned about the granularity of this,and also,because my values have a peak of 485 now, it's all shown in a blue nuances.

        Seems I did a piss poor job of extracting and generalising the routine from where I was using it. I've updated ColorRamp1785 with the improved version used below.

        But soon I will probably have higher values , maybe 1000,maybe 100000 ... it's not as easy as I thought(looking on your code) to deal with those high numbers as well.

        The following shows a few different possibilities. Try running it with a few of the following command lines to see the effects:

        >euclid -MAPPING=C ## the original 1021 color ramp >euclid -MAPPING=C -CENTER ## Same centered >euclid -MAPPING=CE ## The enhanced 1785 color ramp >euclid -MAPPING=CE -CENTER >euclid -MAPPING=BW ## A grey scale >euclid -MAPPING=BW -CENTER

        You can also increase the size -SIZE=nnnn, but it just takes longer :)

        #! perl -slw use strict; use GD; our $MAPPING ||= 'CE'; our $SIZE ||= 500; our $CENTER ||= 0; sub euclid { my( $x, $y ) = @_; return sqrt( $x**2 + $y**2 ); } my $img = GD::Image->new( $SIZE, $SIZE, 1 ); my $max = $CENTER ? euclid( $SIZE/2, $SIZE/2 ) : euclid( $SIZE, $SIZE +); for my $y ( 0 .. $SIZE-1 ) { for my $x ( 0 .. $SIZE-1 ) { my $euclid = $CENTER ? euclid( $x - ( $SIZE/2 ), $y - ( $SIZE/ +2 ) ) : euclid( $x, $y ); my $color = $MAPPING eq 'BW' ? colorRampGrey( $euclid, 0, $max ) : $MAPPING eq 'C' ? colorRamp1021( $euclid, 0, $max ) : colorRamp1785( $euclid, 0, $max );; $img->setPixel( $x, $y, $color ); } } open PNG, '>:raw', "euclid.png" or die $!; print PNG $img->png; close PNG; system 'euclid.png'; exit; sub rgb2n{ unpack 'N', pack 'CCCC', 0, @_ } BEGIN { my %map = ( 255 => sub{ 0, 0, $_[0] * 255 }, 510 => sub{ 0, $_[0]*255, 255 }, 765 => sub{ 0, 255, (1-$_[0])*255 }, 1020 => sub{ $_[0]*255, 255, 0 }, 1275 => sub{ 255, (1-$_[0])*255, 0 }, 1530 => sub{ 255, 0, $_[0]*255 }, 1785 => sub{ 255, $_[0]*255, 255 }, ); my @map = sort{ $::a <=> $::b } keys %map; sub colorRamp1785 { my( $v, $vmin, $vmax ) = @_; $v = $vmax if $v > $vmax; $v = $vmin if $v < $vmin; $v = ( $v - $vmin ) / ( $vmax - $vmin ); $v *= 1785; $v < $_ and return rgb2n( $map{ $_ }->( $v % 255 / 256 ) ) for + @map; } } sub colorRamp1021 { my( $v, $vmin, $vmax ) = @_; my( $r, $g, $b ) = (1) x 3; $v = $vmax if $v > $vmax; $v = $vmin if $v < $vmin; my $dv = $vmax - $vmin; if( $v < ( $vmin + 0.25*$dv ) ) { $r = 0; $g = 4 * ($v - $vmin) / $dv; } elsif( $v < ( $vmin + 0.5 * $dv ) ) { $r = 0; $b = 1 + 4 * ($vmin + 0.25 * $dv - $v) / $dv; } elsif( $v < ( $vmin + 0.75 * $dv ) ) { $r = 4 * ($v - $vmin - 0.5 * $dv) / $dv; $b = 0; } else { $g = 1 + 4 * ($vmin + 0.75 * $dv - $v) / $dv; $b = 0; } return rgb2n( $r*255, $g*255, $b*255 ); } sub colorRampGrey { my( $v, $vmin, $vmax ) = @_; $v = $vmax if $v > $vmax; $v = $vmin if $v < $vmin; $v = ( $v - $vmin ) / ( $vmax - $vmin ); return rgb2n( ( $v * 255 ) x 3 ); }

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Mapping function values to colors
by kennethk (Abbot) on Dec 10, 2008 at 00:44 UTC

    Umm, perl?

    Perhaps, rather than jumping all the way to false color plots, you might consider starting with gray scale, with either linear or logarithmic scale for intensity, depending on your value set.