Create new colorbar

Hello,

We would like to create a new colorbar based on the diverging colormaps available in Matplotlib.

https://matplotlib.org/stable/users/explain/colors/colormaps.html

I read this website regarding AFNI Colorscales,

https://afni.nimh.nih.gov/pub/dist/doc/OLD/afni_colorscale.html

However, it is still not clear to me how to create it and make it available for the GUI. Could you please give some advice?

Thanks in advance,
Cesar

Ps. We will still love AFNI colorbars
It

Hi, Cesar-

Sure, no worries. Out of curiosity which cbar are you using?

Here is a Python script I wrote to make a list of matplotlib cmap names into their own *.pal files for reading into AFNI. Just running this as-is will produce a list of 2 *.pal files, and you can change this to whatever cbar names you want:

#!/usr/bin/env python

# Turn a matplotlib cmap into an AFNI-style colorbar file (*.pal),
# which is basically a single column of 256 hex values, with the
# cbar/cmap name at the top.  This program writes out the *.pal files
# for a list provided by the user (search for "USER LIST" below).
#
# A list of potential cmaps are here:
# https://matplotlib.org/stable/users/explain/colors/colormaps.html
# ... and we show a full list here, and probably one does not need the
# "*_r" ones, because AFNI cbars can be inverted.
#
# ver  : 1.0 (20 Sep 2023)
# auth : PA Taylor (SSCC, NIMH, NIH, USA)  
# -----------------------------------------------------------------------

import copy 
import numpy             as np
import matplotlib        as mpl
import matplotlib.pyplot as plt

def rgb_to_hex(RGB):
    '''Hexify an RBG triplet, where each element value is [0,255].'''
    return '#{:02x}{:02x}{:02x}'. format(RGB[0], RGB[1], RGB[2])


if __name__ == "__main__" :

    # -------------------- list all cmaps ----------------------------

    # list all cmap names
    all_cname = [ccc for ccc in plt.colormaps()]
    all_cname.sort()
    N_cname   = len(all_cname)
    print("++ All cmap names")
    for n in range(N_cname):
        print(" {:15s} ".format(all_cname[n]), end='')
        if n % 6 == 0 :
            print('')
    print('\n'+ '-'*40)

    # ----------------------- make outputs ------------------------------

    # USER LIST: make your own list of cmaps of interest from the
    # above list (just an initial example list here)
    my_cmaps = ['PiYG', 'PRGn']

    Ncolor = 256                           # num color values
    carr   = np.linspace(0, 1, Ncolor)     # array of values to get from cmap

    for ccc in my_cmaps:

        # initialize array of ints
        A    = np.zeros((Ncolor, 4), dtype=int)
        cmap = mpl.colormaps[ccc]
        # fill in values in the arry
        A[:, :] = cmap(carr) * 255

        fname = ccc + '.pal'
        print("++ Writing {}".format(fname))

        # write out column of hex values, with cbar name in first line
        fff = open(fname, 'w')
        fff.write(ccc + '\n')
        for j in range(Ncolor):
            # invert nums, so what is the "left" side of cbar in link
            # above appears as the lower value in initial cbar
            i = Ncolor-j-1 
            fff.write("{}\n".format(rgb_to_hex(A[i,:3])))
        fff.close()

    print("++ Done")

To load+use the cbar in AFNI:

  • Put the cbar in the directory you want and fire up the GUI.
  • Load an overlay dset
  • Right-click the 'Olay' above the cbar in the GUI
  • Select 'Read in palette', and choose your *.pal file of interest
  • Right-click the cbar image itself, and scroll down to the bottom, where your new *.pal file is
    ... and that should give you the cbar/cmap/pbar to use.

--pt

Thank you Paul. This is great. we will try it and let you know if we have any issue.

Personally, I usually employ the following ones (in this order):

  • Spectrum:red_to_blue
  • Spectrum:yellow_to_cyan
  • Spectrum:yellow_to_red (usually inverse)
  • Viridis / Magma or a similar one

Hi, Cesar-

Cool. I was wondering what new colorbar from that matplotlib list you were aiming to use?

--pt

Hi Paul,

We would like to use the bwr or seismic of the diverging scales.
The point is that we are not using them yet, because they are not in AFNI :slight_smile:

Cesar

Okeydoke, cool.

There is also the alpha+boxed functionality for transparent thresholding, which might serve a similar purpose.

--pt

Yes, that's true and we use it very often, but we don't want to use any thresholding sometimes :stuck_out_tongue_winking_eye:

@Gang will be happy to hear that, certainly!

--pt