View Raw SPL
/*****************************************************************************
*                                                                            *
*   PARULINE.SPL   Copyright (C) 2021 DSP Development Corporation            *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Generate a colormap of blue, green, orange, yellow          *
*                                                                            *
*   Revisions:   30 Mar 2021  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/


#if @HELP_PARULINE

    PARULINE

    Purpose: Generates a colormap of blue, green, orange, yellow.

    Syntax:  PARULINE(len)

               len - optional colormap length, defaults to
                     the length of the current colormap


    Returns: A table of RGB triples suitable for the SETCOLORMAP function.

    Example:
             clen = length(getcolormap());
             density(ravel(rep(0..(clen-1), 32), clen)');
             paruline;

             Creates a table of 32 x colormap length RBG values and
             displays the resulting colors. The resulting image is a
             vertical plot of colors ranging from blue (lowest) to
             green to orange to yellow (highest).

    Example:
             paruline(256);showcmap

             Creates a table of 32 x 256 length RBG values and
             displays the resulting colors. The resulting image is a
             vertical plot of colors ranging from blue (lowest) to
             green to to orange to yellow (highest).

    Remarks:
             PARULINE() by itself sets the colormap and shading.

             a = paruline() or setcolormap(paruline()) returns the rgb
             values. In this case, use SETSHADING to make the new colormap
             take effect on an existing density or 2D plot.

             PARULINE is an independently designed, approximately
             perceptually uniform colormap featuring a smooth,
             monotonically increasing luminance profile. Its hue
             progression draws on the natural coloration found in
             the Northern Parula warbler, producing a balanced blue to
             yellow aesthetic that is both visually appealing and
             scientifically practical. 

             See CIVIDIS, INFERNO, MAGMA, PLASMA and VIRIDIS for 
             perceptually uniform colormaps.
             
    See Also:
             Autumn
             Bone
             Cividis
             Cool
             Copper
             Gray
             Hot
             Hsv
             Inferno
             Magma
             Pink
             Plasma
             Rainbow
             Setcolormap
             Setshading
             Showcmap
             Spring
             Summer
             Viridis
             Winter
#endif


/* paruline colormap */
paruline(cmaplen)
{
        local cmap, rgb;
        static coef = {};

        if (argc < 1)
        {
                cmaplen = length(getcolormap());
        }

        /* orginal colormap */
        cmap = getcolormap();

        if (isempty(coef))
        {
                /* set blue, green, orange, yellow colormap */
                setshading(
                                "darkmagenta",
                                "dodgerblue", 
                                "royalblue", 
                                "dodgerblue", 
                                "cornflowerblue", 
                                "cyan", 
                                "mediumaqua",
                                "springgreen", 
                                "goldenrod", 
                                "orange", 
                                "orange", 
                                "gold", 
                                "yellow");

                /* rgb values */
                rgb = getcolormap();

                /* 4th order polynomial fit */
                coef = polyfit(rgb, 4);
        }

        /* derive RGB colors */
        rgb = polyval(coef, linspace(0, 255, cmaplen), 0);

        /* limits */
        rgb = rescale(rgb, 0, 1);

        /* clamp red channel to force yellow end */
        rgb = ravel(paruline_clamp(col(rgb, 1), 1), col(rgb, 2), col(rgb, 3));

        /* brighten all colors */
        rgb = brighten(0.15, rgb);

        if (outargc == 0)
        {
                /* set the colormap and shading */
                setplotshading(rgb);
        }
        else
        {
                /* restore original map */
                setcolormap(cmap);

                /* set RGB properties */
                setrgbprops(rgb);
                
                /* return the colormap */
                return(rgb);
        }
}


/* peg to upper limit */
paruline_clamp(s, tmax = inf)
{
        local maxidx, t;

        /* start of threshold */
        maxidx = find(s >= tmax, 1);

        /* copy */
        t = s;

        if (length(maxidx) > 0)
        {
                t[maxidx[1]..end] = tmax;
        }

        return(t);
}