I have a list of values which should be plotted to a map with a certain color.
The plotting to the map is already done, but I need to figure out a way to map the value n
to a color that represents its value.
An example and my solution so far is to normalize the values based on the min
and max
and then assign them to hex color 0
for the lowest and 255
for the highest. This of course limits my self to the grey scale. Here is the code:
$color = ($value / $max) * 255 // (min is zero)
But how to do this if the values should go from blue to red for instance? Is there any common libraries or tools that can solve this? So far I haven't been able to locate any.
In mathematics, the four color theorem, or the four color map theorem, states that no more than four colors are required to color the regions of any map so that no two adjacent regions have the same color.
Several of the coloring methods, including `Beta', `Charge', and `Occupancy', describe a range of floating point values rather than a set of names. These are colored via the color scale, which is a list of 1024 smoothly changing colors. There are many color gradations available.
Qualitative colour Schemes Qualitative schemes are best suited to represent nominal or categorical data, they have no inherent ordering. It is best to not have more than 10 colours as it then becomes hard to distinguish between categories.
There might be libs to do that. However let's get a short warm up into the general principles. In general you have following options:
$coloridx=array(0=>'#FFFFFF',1=>'#FFEE00',...);
If you include algorithms in your considerations you must understand that there is no true
or false
. It all depends on what you would like to implement. There might be occasions where it makes sense to render variations of green into n=0..10
and then have red to black in everything beyond n>10
. Caps and multipliers help to set accents. Things like that.
One way of implementing a linear gradient would be:
function lineargradient($ra,$ga,$ba,$rz,$gz,$bz,$iterationnr) {
$colorindex = array();
for($iterationc=1; $iterationc<=$iterationnr; $iterationc++) {
$iterationdiff = $iterationnr-$iterationc;
$colorindex[] = '#'.
dechex(intval((($ra*$iterationc)+($rz*$iterationdiff))/$iterationnr)).
dechex(intval((($ga*$iterationc)+($gz*$iterationdiff))/$iterationnr)).
dechex(intval((($ba*$iterationc)+($bz*$iterationdiff))/$iterationnr));
}
return $colorindex;
}
$colorindex = lineargradient(
100, 0, 0, // rgb of the start color
0, 255, 255, // rgb of the end color
256 // number of colors in your linear gradient
);
$color = $colorindex[$value];
I UPDATED the code to add dechex, which feeds back on the comments.
Colors values are representations. Numeric colors as well as hexadecimal colors. A "not grayscale" color contains at least 2 different informations: Red value, green value or blue values may be different. Performing operation on its representation gives wrong result. The 'Mapping" must then be performed on each pieces of information. You need to extract red, green and blue values, perform the mapping seperatly, then build the representation of the result color. Here is a quick helper that use a "min color" and "max color", performs mapping on red, green and blue values, according to the "n" value you need to work with, then return the result color in hexadecimal string. It works for any colors or gray scale color as well.
function linear_color($from, $to, $ratio) {
// normalize ralio
$ratio = $ratio<0?0:($ratio>1?1:$ratio);
// unsure colors are numeric values
if(!is_numeric($from))$from=hexdec($from);
if(!is_numeric($to))$to=hexdec($to);
$rf = 0xFF & ($from >> 0x10);
$gf = 0xFF & ($from >> 0x8);
$bf = 0xFF & $from;
$rt = 0xFF & ($to >> 0x10);
$gt = 0xFF & ($to >> 0x8);
$bt = 0xFF & $to;
return str_pad( dechex(($bf + (($bt-$bf)*$ratio)) + ($gf + (($gt-$gf)*$ratio) << 0x8) + ($rf + (($rt-$rf)*$ratio) << 0x10)), 6,'0',STR_PAD_LEFT);
}
Just specify 2 colors as numeric value or hexadecimal string (without hash!) like this :
$color_from = hexdec('c2c2c2');
$color_to = hexdec('1eb02b');
for($i=-0.2; $i<=1.3; $i+=0.04){
echo '<div style="background-color: #';
echo linear_color($color_from, $color_to, $i);
echo '">';
echo 'Result color when n = <strong>'.$i.'</strong>';
echo '</div>';
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With