Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion brainspace/plotting/colormaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,57 @@
[70, 130, 180, 255],
[196, 58, 250, 255]], dtype=np.uint8)

colormaps = {'yeo7': yeo7_colors}
eco_kos_colors = np.array([[0, 0, 0, 255],
[126, 40, 127, 255],
[51, 104, 156, 255],
[167, 210, 140, 255],
[254, 205, 8, 255],
[255, 253, 25, 255]], dtype=np.uint8)

# 5-step Spectral palette (control points from ColorBrewer 2.0, Apache 2.0).
# Reference: https://colorbrewer2.org
spec_5_colors = np.array([[0, 0, 0, 255],
[50, 136, 189, 255],
[171, 221, 164, 255],
[235, 235, 181, 255],
[253, 174, 97, 255],
[213, 62, 79, 255]], dtype=np.uint8)


def _interp_lut(stops, n=256):
"""Build a 256-row RGBA uint8 lookup by linearly interpolating ``stops``.

``stops`` is an (k, 3) or (k, 4) array of RGB(A) values in [0, 255].
Output always has alpha = 255 unless explicit alphas are provided.
"""
stops = np.asarray(stops, dtype=np.float64)
k = stops.shape[0]
xs = np.linspace(0.0, 1.0, k)
grid = np.linspace(0.0, 1.0, n)
cols = stops.shape[1]
out = np.empty((n, 4), dtype=np.float64)
for c in range(min(cols, 4)):
out[:, c] = np.interp(grid, xs, stops[:, c])
if cols < 4:
out[:, 3] = 255.0
return np.clip(out, 0, 255).astype(np.uint8)


# Diverging blue->grey->red colormap. Built programmatically from 5 control
# points to keep the file small and reviewable instead of hand-listing 256
# RGB tuples.
_BuGyRd_stops = np.array([
[33, 113, 181], # blue
[120, 170, 210], # light blue
[200, 200, 200], # grey midpoint
[220, 90, 60], # warm red
[103, 0, 13], # dark red
])
BuGyRd = _interp_lut(_BuGyRd_stops, n=256)

colormaps = {
'yeo7': yeo7_colors,
'eco_kos': eco_kos_colors,
'spec_5': spec_5_colors,
'BuGyRd': BuGyRd,
}
8 changes: 7 additions & 1 deletion brainspace/plotting/surface_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@
orientations = {'medial': (0, -90, -90),
'lateral': (0, 90, 90),
'ventral': (0, 180, 0),
'dorsal': (0, 0, 0)}
'dorsal': (0, 0, 0),
'anterior': (90, 90, 90),
'posterior': (270, 90, 90),
# 'flatL'/'flatR' assume an already-flattened surface; the
# camera angle alone does not flatten a folded mesh.
'flatL': (0, 180, 90),
'flatR': (0, 180, 270)}


def _add_colorbar(ren, lut, location, **cb_kwds):
Expand Down
31 changes: 31 additions & 0 deletions brainspace/tests/test_colormaps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Tests for plotting.colormaps registrations and BuGyRd interpolation (#91)."""

import numpy as np

from brainspace.plotting.colormaps import (
colormaps, yeo7_colors, eco_kos_colors, spec_5_colors, BuGyRd,
)


def test_registered_names():
for name in ('yeo7', 'eco_kos', 'spec_5', 'BuGyRd'):
assert name in colormaps
cm = colormaps[name]
assert cm.dtype == np.uint8
assert cm.shape[1] == 4


def test_BuGyRd_is_256_smooth_lut():
assert BuGyRd.shape == (256, 4)
assert np.all(BuGyRd[:, 3] == 255)
# Endpoints should match the configured stops (within rounding).
np.testing.assert_array_equal(BuGyRd[0, :3], [33, 113, 181])
np.testing.assert_array_equal(BuGyRd[-1, :3], [103, 0, 13])
# Smoothness: no large per-row jump in any channel.
diffs = np.abs(np.diff(BuGyRd[:, :3].astype(int), axis=0))
assert diffs.max() < 8


def test_categorical_palettes_have_alpha_255():
for cm in (yeo7_colors, eco_kos_colors, spec_5_colors):
assert np.all(cm[:, 3] == 255)
Loading