Skip to content

adammaj1/1D-RGB-color-gradient

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

1D (univariate) continous ( smooth) color gradients ( colormaps) implemented in c and gnuplot for:

  • real type data normalized to [0,1] range ( univariate map)
  • integer ( or unsigned char) data normalized to [0.255] range

and how to manipulate them ( invert, join, turned into a cyclic or wrapped color gradient )

TOC

Introduction

Why Should Engineers and Scientists Be Worried About Color? by Rogowitz & Treinish 1996

What should and what should not do colormap/gradient in scientific visualisation?

Continous gradient manipulations

Gradient function:

double ModifyPosition(const double position, const GradientJoiningType GradientJoining){
	
	// input position  should be in  [0,1] range 
	double p = position; // p = local copy of position
	// if position > 1 then we have repetition of colors = periodic function = wave   
	
	
	switch(GradientJoining){
	
		case no : {break;} // return input position witout modifications
		
		// periodic waves with different joinings
		case steps : {	p = p * segments; // periodic  = change range
				p = frac(p); 
    				break;}
    				
		case tubes : {	p = p * segments; // periodic = change range
				int ip = (int)p;
      				p = p-ip; // fractional part 
      				if (ip % 2) {p = 1.0-p;} // reverse gradient
				break;}
		default:{}
	}
	return p; // output in [0,1] range
}

Step function:

  • highliths the boundaries of level sets

Examples

Example videos by Maths Town:

Tubes

Examples of 1D colour maps/gradients ( mostly continous)

Examples by hue:

// d.c 
		// multihue		
  		case RainbowHSV: 	{GiveRGB_RainbowHSV(p, rgb); break;}
  		case Linas: 		{GiveRGB_Linas(p, rgb); break;}
  		case Linas2: 		{GiveRGB_Linas2(p, rgb); break;}
  		case RainbowFractalizer:{GiveRGB_RainbowFractalizer(p, rgb); break;} //
  		case OrangeBlueFractalizer: {GiveRGB_OrangeBlueFractalizer(p, rgb); break;} 
  		case Magma: 		{GiveRGB_Magma(p, rgb); break;}
  		case Cubehelix:	{GiveRGB_Cubehelix(p, rgb); break;}
  		case RainbowHSP: 	{GiveRGB_RainbowHSP(p, rgb); break;}
  		case HSP:	 	{GiveRGB_HSP(p, rgb); break;}
  		// diverging 
  		case CoolWarm: 	{GiveRGB_CoolWarm(p, rgb); break;}
  		// single hue
  		case GreenCubic: 		{GiveRGB_GreenCubic(p, rgb); break;}
  		case GreenCubicInv: 		{GiveRGB_GreenCubicInv(p, rgb); break;}
  		case GreenCubicRoot: 		{GiveRGB_GreenCubicRoot(p, rgb); break;}
  		case BlueCubicInv: 		{GiveRGB_BlueCubicInv(p, rgb); break;}
  		case RedCubicInv: 		{GiveRGB_RedCubicInv(p, rgb); break;}
  		case GreenSin: 		{GiveRGB_GreenSin(p, rgb); break;}
  		 
  		// no hue = gray, one function for all gray gradients
  		case Linear: 	
  		case Quadratic: 	
  		case Cubic: 
  		case CubicInv:		
  		case Sqrt: 
  		case Root:		
  		case Gamma: 		
  		case Sin: 		
  		case LSin: 		
  		case SinExp: 	
  		case Smooth: 	
  		Tanh : {GiveRGB_Gray(p, ColorTransferFunction, rgb); break;}  

Rainbow colormap or sawtooth rainbow or hsv

Rainbow


Compare with gnuplot image

Features of rainbow gradient:

HSV


"cyclic colormap traversing HSV color space. The map is obtained by linearly varying the hue through all possible values while keeping constant maximum saturation and value."

set palette model HSV functions gray,1,1

or in C#

for(double i = 0; i < 1; i+=0.01)
{
    ColorRGB c = HSL2RGB(i, 0.5, 0.5);
    //do something with the color
}

RGB

Description by Laurence Gonsalves

It can be done directly in RGB space by a linear interpolation (in RGB) between each consecutive pair in this sequence:

  • #ff0000 = red = rgb(255,0,0)
  • #ffff00 = yellow = rgb (255,255,0)
  • #00ff00 = green = rgb(0,255,0)
  • #00ffff = cyan = rgb(0,255,255)
  • #0000ff = blue = rgb(0,0,255)
  • #ff00ff = magenta = rgb(255,0,255)
  • #ff0000 = red = rgb (255,0,0)

Note that only one component changes for each interpolation, which simplifies things.

See css linear gradient

linear-gradient(to right, red,orange,yellow,green,blue,indigo,violet);

or python:

def rainbow():
  r, g, b = 255, 0, 0
  for g in range(256):
    yield r, g, b
  for r in range(255, -1, -1):
    yield r, g, b
  for b in range(256):
    yield r, g, b
  for g in range(255, -1, -1):
    yield r, g, b
  for r in range(256):
    yield r, g, b
  for b in range(255, -1, -1):
    yield r, g, b

c function:

modifications



See also

var spaces = [
  {
    name: "Rainbow (HSL)",
    color: function(t) {
      return d3.hsl(t * 360, 1, .5);
    }
  },
  {
    name: "Rainbow (HCL)",
    color: function(t) {
      return d3.hcl(t * 360, 100, 55);
    }
  },
  {
    name: "Rainbow (Cubehelix)",
    color: d3.scale.cubehelix()
        .domain([0, .5, 1])
        .range([
          d3.hsl(-100, 0.75, 0.35),
          d3.hsl(  80, 1.50, 0.80),
          d3.hsl( 260, 0.75, 0.35)
        ])
  }
];

Linas colormap


Your new colormap is different and ugly-ish. The line between red-and-yellow is much much worse than before. the red-yellow discontinuity is ... confusing, annoying. .. to me, at least. Linas

Features of Linas gradient:

  • non monotone ( see black curve)
  • complex = consist of 4 monotone segments
  • the red-yellow discontinuity can be seen as a jump discontinuity of the green, red and black curve at gradient position 0.753333
0.743333	 210	166	0
0.746667	 210	166	0
0.750000	 210	166	0
0.753333	 210	166	0
0.756667	 210	150	0
0.760000	 210	150	0
0.763333	 210	148	0
0.766667	 211	146	0
0.770000	 212	144	1
0.773333	 213	142	1
0.776667	 213	142	1
0.780000	 213	140	1

so R jumps from 166 to 150

I have chaged it manually :

  • only 5 points = 4 linear segments
  • last point ( position) changed to 1.00000
0.000000	0	0	0
0.250000	0	0	177
0.500000	0	175	0
0.750000	210	156	0
1.000000	252	36	19

or in the 0-1 normalized 4 columns form:

0.000000 0.000000 0.000000 0.000000
0.250000 0.000000 0.000000 0.458823
0.500000 0.000000 0.686274 0.000000
0.750000 0.823529 0.611764 0.000000
1.000000 0.988235 0.141176 0.074509

which can be used by gnuplot command:

load "linas.pal"

and then check:

 show palette gradient
  0. gray=0.0000, (r,g,b)=(0.0000,0.0000,0.0000), #000000 =   0   0   0
  1. gray=0.2500, (r,g,b)=(0.0000,0.0000,0.4588), #000075 =   0   0 117
  2. gray=0.5000, (r,g,b)=(0.0000,0.6863,0.0000), #00af00 =   0 175   0
  3. gray=0.7500, (r,g,b)=(0.8235,0.6118,0.0000), #d29c00 = 210 156   0
  4. gray=1.0000, (r,g,b)=(0.9882,0.1412,0.0745), #fc2413 = 252  36  19

Now one can compute: 4 functions for each color channel ( 12 functions) using polysolve by P. Lutus. Result:


C code for Linas gradient:

  • old (= bad): funcion GiveLinasColor from p.c
  • new (= good): function GiveLinas2Color from p.c

Examples of use: Linas art gallery - my version of Linas programs with old gradient

modifications:





Magma colormap


c function = GiveMagmaColor from p.c file

lightness is monotone

Steps:

Tubes:

RainbowFractalizer

It is rainbow gradient from the Fractalizer program.

It has 7 segments and black color

lightness is non monotone


c function = GiveRainbowFractalizer from d.c file

Steps:

Tubes:

See also:

OrangeBlueFractalizer

It is orange-blue gradient from the Fractalizer program.

Features:

  • lightness is non monotone
  • Looks like diverging gradient
  • it has the same color on both ends
  • It has 5 segments:
    • black
    • orange (255,80,0)
    • yellow ( 255, 255,128) = Unmellow Yellow = canary
    • white
    • blue
    • black


c function = GiveOrangeBlueFractalizer from d.c file

Steps:


Tubes:


See also:

Gray Linear colormap

Linear function


c function:

  • (old) GiveGrayColorL from p.c file
  • (new) GiveRGB_Gray case Linear from d.c file

Effect of joining gradients ( segments of the same gradient combined):

Steps:

Tubes:

Example image with use of such gradient:

code and description is in the commons

Gray Sin: effect of a sine wave

only ascending wave ( f = 1/2)


Adam Sakareassen : "The colours simply fade from black to white in a cycle. This wave is generated with the sin function. This method is useful when blending layers to create light to dark contrasts."

Steps:

Tubes:

c function = GiveRGB_Gray from d.c file

Similar to

/* SmoothStep 
it needs   position in range [0.0, 1.0]  
*/
double d = (3.0 -2.0*position)* position*position;

Examples of use :

Gray LSine: effect of a sine wave superimposed on a ramp function

It is based on the The Colour Map Test Image by Peter Kovesi


c function = GiveGrayColorLSine from d.c file

Steps:

Tubes:

Gray SinExp: effect of a sine(exp) wave

An exponential chirp waveform; a sinusoidal wave that increases in frequency exponentially over time


c function = GiveGrayColorLSineExp from d.c file

See als:

Steps:

Tubes:

see also:

Gray NL2 = Quadratic colormap


Steps:

Tubes:

Gray NL3 =Cubic colormap


Steps:

Tubes:

CubicInv


Steps:

Tubes:

GrayGamma

Nonlinear gamma-corrected black and white palette


It is from gnuplot:

gamma = 2.2
color(gray) = gray**(1./gamma)
set palette model RGB functions color(gray), color(gray), color(gray) # A gamma-corrected black and white palette

Steps:


Tubes:


Gray Sqrt colormap


Steps:

Gradient can be inverted and joined, which converts "boring rectangle to into a stunning three dimensional glossy pipe":


Tanh


Steps:

Tubes:

GreenCubic colormap


More is here:

Features of the green colormap ( gradient):

  • shows the order of the data ( thru brightness)
  • highlight the boundary ( thru nonlinear green = 1.0 - position^3
// from green to black = 
void GiveColorGreen(double position, double c[]){
	
	
  double X =  1.0- (position*position*position);
  // change range 
  c[0] = 0; //R
  c[1] = X; // G
  c[2] = 0; // B	
}

Steps:

Tubes:

GreenCubicRoot colormap


Steps:

Tubes:

Smooth CoolWarm diverging colormap



Description by Kenneth Moreland

  • blue-red diverging
  • It is a diverging (double-ended) color map with a smooth transition in the middle to prevent artifacts at the midpoint

code:

Steps:

Tubes:

Bent Cool Warm ( diverging )

Description by Kenneth Moreland

  • This is a similar color map to the previous except that the luminance is interpolated linearly with a sharp bend in the middle. This makes for less washed out colors in the middle, but also creates an artifact at the midpoint.
  • "I ... define it with only 3 colors. ... I made the middle point a little less bright (to avoid problems with colors at the edge of what can physically be displayed). ""

Cubehelix

colour scheme developed by Dave Green:


the colour scheme spirals (as a squashed helix) around the diagonal of the RGB colour cube

Steps:

Tubes:


See also:

arctic

The GRID-Arendal Maps & Graphics Library is an on-going project to collect and catalogue all graphic products that have been prepared for publications and web-sites from the last 15 years in a wide range of themes related to environment and sustainable development

One can see here:

  • it is diverging gradient. It is also non symetrical ( peak is nota at 0.5 )
  • gradient info from cpt-city: −5000 … 4000, mixed, RGB, 110 segments
  • jump discontinuity of blue and red curves
  • curves are not smooth, probably because of numerical conversion from other format

See:

default Fractint map

It seem that is a multi purpose gradient

It was made from default.map with gnuplot code:

set palette file "default.map" using ($1/255):($2/255):($3/255) 
set terminal png
set output "fractint.png"
test palette

See:

guide to working with the source code

conventions

  • image file names = ColorTransferFunction_GradientJoining[_2D].png wher optional part 2D means 2D profiles of color
  • ColorTransferFunction takes input in [0,1] and gives output in [0,1] range

API Reference

simple one file c programs which

  • do not need any extra libraries
  • can be run from console
  • compiled with gcc
  • multiplatform

How to compile and run is described in the comments of c files

files

All my images here are made with

  • c console program with gradients made of functions
  • Image Magic convert console program
  • gnuplot scripts

to make all images go to src directory and:

make

programs

Makefile

c console programs:

  • d.c - c program with similar to p.c but with output in range [0,1]
  • s.c - c progrm for create enum from array of strings (lazy and naive method but works for me)
  • p.c - c program with output in range [0,255]. It creates 2 files (*.ppm and *.txt) for each colormap ( explicit transfer function)
  • h.c - c code for creating *.txt files with data. It converts hsv to rgb
  • j.c - c program which creates gradient files in json format for colormeasure . It uses explicit transfer functions. Output is in [0,1] range

gnuplot programs

  • plot.gp - gnuplot program which creates *.png fils from *.txt files
  • plot2.gp - gnuplot code for 3d rgb profile
  • cubehelix.gp - gnuplot code for 2d and 3d rgb profile of cubehelix color map
  • plot3d.gp

python programs

make files

  • Makefile : compiles d.c, run it and plot.gp

palettes

pal files ( files with gnuplot code, use load command )

json files in src dir for colormeasure

similar projects

technical notes

I'm not an expert in the color, so many errors can be here. If you will find them let me know: issues or wikibooks

Contributors

Program uses code from:

Program uses idea from :

How to contribute ?

Contributors are wellcome.

How to do it ( after darktable ) :

  • Write a blog about it
  • Create a tutorial for it
  • Help expand the user wiki
  • Answer questions on the user mailing list
  • Share your ideas on the developer mailing list
  • Test releases
  • Review pull requests
  • Start hacking on the program and see developer's guide

See also:

License

licence

Star History

Star History Chart

Git

cd existing_folder
git add .
git commit -m "Initial commit"
git push -u origin main
  git clone git@github.com:adammaj1/1D-RGB-color-gradient.git

Subdirectory

mkdir images
git add *.png
git mv  *.png ./images
git commit -m "move"
git push -u origin main

then link the images:

![](./images/n.png "description") 

to overwrite

git mv -f 

local repo : ~/1D-RGB-color-gradient