cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
Craige_Hales
Super User
Gradient Function

@ClusteredMining  asked  Making heat map- How do I define the values for each color in the gradient?  . This is not exactly answering the question, but maybe. Using the GradientFunction and a color list, it is possible to get a really sharp boundary in a third color. Many variations are possible by tailoring a long list of colors to produce the sharp boundaries. Or blurry, which may look prettier.

The GradientFunction needs a bit of JSL that can answer the question "what is the Z value here?" That function may not be readily available because the data is in a table, and not nicely gridded.

edit: You should probably make totalWidth bigger rather than smaller; it controls the number of colors in the colorList which controls the precision of the edge placement. You should probably make the grid value a little bigger too. grid=100 and totalWidth=100 seems more reasonable than 50 and 10.


// these are in units of the Z value
range = {100, 400}; // the range of the color list; the formula a*b on the axis 10..20 makes these numbers
targetValue = 200; // happens to go through the corners for this example.

// grid: this determines how many points are evaluated by GradientFunction
grid = 50; // subdivisions, more looks smoother, is slower. typically 50 to 500. 667 may be a limit.

// how many colors in the colorList
thick = 0.050; // thickness of division line, can be 0. 50% is really fat (0.5)
totalWidth = 10; // make this smaller for a blurred edge, maybe 10 or 100 instead of 1000, which has a sharper edge
targetWidth = Round( thick * totalWidth );// making the green target about 10%, so kind of thick
otherwidth = totalWidth - targetWidth; // the ratios, below, divides this in parts
lowRatio = (targetValue - range[1]) / (range[2] - range[1]);// the red
highRatio = 1 - lowRatio;// the blue

// this list is a bunch of repeated reds, a few greens, and a 
// bunch of blues. The greens are centered at the targetValue.
colorList = {};
Insert Into( colorList, As List( Repeat( RGB Color( .4, 0, 0 ), Round( otherwidth * lowRatio ) ) ) );
Insert Into( colorList, As List( Repeat( RGB Color( 0, .6, 0 ), targetWidth ) ) );
Insert Into( colorList, As List( Repeat( RGB Color( 0, 0, .4 ), Round( otherwidth * highRatio ) ) ) );

New Window( "target=" || Char( targetValue ),
    g = Graph Box(
        X Scale( 10, 20 ),
        Y Scale( 10, 20 ),
        framesize( 600, 400 ),
        Gradient Function(
            a * b,
            a,
            b,
            Matrix( range ), // range to map the colors onto
            Z Color( colorList ),
            <<xgrid( X Origin(), X Origin() + X Range(), X Range() / (Floor( grid * H Size() / V Size() )) ),
            <<ygrid( Y Origin(), Y Origin() + Y Range(), Y Range() / (Floor( grid )) ), 

        );
        If( 1, // testing...change to zero to remove the white Z lettering
            Text Color( "white" );
            For( a = X Origin(), a < X Origin() + X Range(), a += X Range() / 9,
                For( b = Y Origin(), b < Y Origin() + Y Range(), b += Y Range() / 9,
                    Marker( Color State( "white" ), {a, b} );
                    Text( CenterJustified, {a, b}, Char( Round( a * b, 2 ) ) );
                )
            );
        );
    )
);

Play with grid, width, and totalThick to get interesting graphs:

A thin sharply defined green region between red and blue.A thin sharply defined green region between red and blue.

Thicker, and still sharp.Thicker, and still sharp.

Thicker, and blurry.Thicker, and blurry.

 

Last Modified: Feb 2, 2022 8:49 AM