Skip to content

Latest commit

 

History

History
142 lines (112 loc) · 5.51 KB

README.md

File metadata and controls

142 lines (112 loc) · 5.51 KB

colorstamps

Python package for 2D colormaps. Most included colormaps are based on the 'CAM02-LCD' colorspace as defined in the package colorspacious (https://pypi.org/project/colorspacious/)

Documentation is hosted at https://colorstamps.readthedocs.io/en/latest/ but a summary follows below:

Installation: pip install colorstamps

Example:

import matplotlib.pyplot as plt
import colorstamps

img = colorstamps.helpers.get_random_data() # numpy array of shape (100,200,2) with 2d data to plot    
rgb, stamp = colorstamps.apply_stamp(img[:,:,0], img[:,:,1], 'peak',
                                   vmin_0 = -1.2, vmax_0 = 1.2,
                                   vmin_1 = -1, vmax_1 = 1,
                                 )

fig, axes = plt.subplots(1,2,figsize=(10,3), dpi = 100)    
axes[0].imshow(rgb)

# show colormap as overlay
overlaid_ax = stamp.overlay_ax(axes[0], lower_left_corner = [0.7,0.85], width = 0.2)
overlaid_ax.set_ylabel(r'$\phi$')
overlaid_ax.set_xlabel(r'$\omega$')

# also show colormap as in separate ax to illustrate functionality
stamp.show_in_ax(axes[1])
axes[1].set_ylabel(r'$\phi$')
axes[1].set_xlabel(r'$\omega$')

Examples of included colormaps are shown below:

Customization

All the colormaps are called by colorstamps.stamps.get_cmap() and the following keyword can be used with either colorstamps.apply_stamp() or colorstamps.stamps.get_cmap() to customize the colormaps:

l: int, the size of the colormap will be (l,l), defaults to 256 if None
  rot: float, rotation of the colormap (where applicable)
  J: array-like of length 2 (float,float), determins min and max luminocity where applicable
  sat: float, maximum saturation where applicable
  limit_sat: string, 'individual' or 'shared'. How saturation is limited for relevant colormaps when colors outside sRGB are required
              'individual': each combination J, hue in the colormap has an individual limit to saturation
              'shared': for each J, all hues share a limit, the maximum where all hues can be represented
  a: range along a-axis, array-like [min,max]
              Used to move the center of the colormap where applicable.
              Defaults to (-1,1) which is then multiplied internally with sat
  b: range along b-axis, see a.
Additionally, for radial colormaps the name may have a postfix separated by a space, i.e. 'cone tr'
  the postfix must be some combination of (t,b) and/or (l,r) which defines the quadrant/side of the colormap to include
  t-> top, b-> bottom, r-> right, l-> left, and 'tr'-> top right, etc.

Evaluation of colormaps

The package also includes a method for evaluating colormaps, by evaluating the distribution of lighness, hue, saturation, and how it can be percieved by those with partial colorblindness

stamp = colorstamps.Stamp('hsv')
fig, ax = stamp.eval()
stamp = colorstamps.Stamp('peak')
fig, ax = stamp.eval()

The package also supports different methods for clipping data to the colormap, using the 'clip' keyword in colorstamps.apply_stamp()

Additional colormaps

Additional colormaps available by converting 1d colormaps in matplotlib to 2d colormaps by varying the lightness along the y-axis:

User-provided colormaps

Custom colormaps may be integrated by providing a numpy array of shape (l,l,3) detailing a 2d colormap instead of a name when calling colorstamps.apply_stamp()

my_cmap = np.zeros((256,256,3))
my_cmap[:,:,0] = np.linspace(0,1,256)[:,np.newaxis]
my_cmap[:,:,2] = np.linspace(0,1,256)[np.newaxis,:]
my_cmap[:,:,1] = 0.5*(my_cmap[:,:,0]+my_cmap[:,:,2])

img = colorstamps.helpers.get_random_data() # numpy array of shape (100,200,2) with 2d data to plot    
fig, ax = plt.subplots(1,1,figsize=(5,3), dpi = 100)    
rgb, stamp = colorstamps.apply_stamp(img[:,:,0], img[:,:,1], my_cmap)

ax.imshow(rgb)
overlaid_ax = stamp.overlay_ax(ax, lower_left_corner = [0.66,0.85], width = 0.2)
overlaid_ax.set_ylabel(r'$\phi$')
overlaid_ax.set_xlabel(r'$\omega$')

Colormaps for line plots

Colormaps can also be used in combination with line plots:

# intensities: array of shape (l,l,n)
# omega: array of shape (l,l)
# phi: array of shape (l,l)
# phase: array of shape (n)

# here l = 5, and n is 41

var_0 = np.array(omega)
var_1 = np.array(phi)
l = phi.shape[0]
rgb, stamp = colorstamps.apply_stamp(var_0, var_1, 'abyss', l = l,
	   vmin_0 = np.min(var_0) - 0.5*(np.max(var_0)-np.min(var_0))/l, 
	   vmax_0 = np.max(var_0) + 0.5*(np.max(var_0)-np.min(var_0))/l,
	   vmin_1 = np.min(var_1) - 0.5*(np.max(var_1)-np.min(var_1))/l, 
	   vmax_1 = np.max(var_1) + 0.5*(np.max(var_1)-np.min(var_1))/l,
	 )


fig, ax = plt.subplots(dpi = 300)
for i, row in enumerate(intensities):
    for j, intensity in enumerate(row):
	    ax.plot(phase, intensity/np.max(intensity), color = rgb[i,j])
	    
ax.set_xticks(phase[::10])
ax.set_xticklabels(phase[::10]%360)
ax.set_ylabel('Amplitude')
ax.set_xlabel('Phase')
ax.set_xlim((0,360))
overlaid_ax = stamp.overlay_ax(ax, lower_left_corner = [0.15,0.25], width = 0.2)
overlaid_ax.set_xlabel(r'$\phi$')
overlaid_ax.set_ylabel(r'$\omega$')

support

Any contributions that would provide additional colormaps for are welcome, as are contributions to increase the functionality.