Skip to content

Commit

Permalink
Merge pull request #1049 from xcube-dev/forman-rename_cm_types
Browse files Browse the repository at this point in the history
Renamed internal color mapping types
  • Loading branch information
forman authored Jul 22, 2024
2 parents 799fe53 + 4e36d30 commit 6c8552a
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 18 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
A UserWarning will be issued for the "stac" data store.


### Other changes

* Renamed internal color mapping types from `"node"`, `"bound"`, `"key"`
into `"continuous"`, `"stepwise"`, `"categorical"`.

## Changes in 1.6.0

### Enhancements
Expand Down
14 changes: 7 additions & 7 deletions test/util/test_cmaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ def test_get_cmap_from_code_type_key(self):
'[1, "#00000000"], '
'[2, "#ff0000aa"], '
'[5, "#ffffffff"]'
'], "type": "key"}'
'], "type": "categorical"}'
)
self.assertIsInstance(cmap, matplotlib.colors.ListedColormap)
self.assertIsInstance(cmap(np.linspace(0, 1, 10)), np.ndarray)
self.assertIsInstance(colormap, Colormap)
self.assertEqual("ucb783473", colormap.cm_name)
self.assertEqual("key", colormap.cm_type)
self.assertEqual("categorical", colormap.cm_type)
self.assertEqual(CUSTOM_CATEGORY.name, colormap.cat_name)
self.assertEqual([1, 2, 3, 5, 6], colormap.values)

Expand All @@ -124,13 +124,13 @@ def test_get_cmap_from_code_type_bound(self):
'[0.0, "#00000000"], '
'[0.6, "#ff0000aa"], '
'[1.0, "#ffffffff"]'
'], "type": "bound"}'
'], "type": "stepwise"}'
)
self.assertIsInstance(cmap, matplotlib.colors.LinearSegmentedColormap)
self.assertIsInstance(cmap(np.linspace(0, 1, 10)), np.ndarray)
self.assertIsInstance(colormap, Colormap)
self.assertEqual("ucb783474", colormap.cm_name)
self.assertEqual("bound", colormap.cm_type)
self.assertEqual("stepwise", colormap.cm_type)
self.assertEqual(CUSTOM_CATEGORY.name, colormap.cat_name)
self.assertEqual((0.0, 0.6, 1.0), colormap.values)

Expand All @@ -148,7 +148,7 @@ def test_get_cmap_from_code_reversed_alpha(self):
self.assertIsInstance(cmap(np.linspace(0, 1, 10)), np.ndarray)
self.assertIsInstance(colormap, Colormap)
self.assertEqual("ucb783475", colormap.cm_name)
self.assertEqual("node", colormap.cm_type)
self.assertEqual("continuous", colormap.cm_type)
self.assertEqual(CUSTOM_CATEGORY.name, colormap.cat_name)
self.assertEqual((0.0, 0.5, 1.0), colormap.values)

Expand All @@ -160,7 +160,7 @@ def test_get_cmap_from_code_invalid(self):
self.assertIsInstance(cmap, matplotlib.colors.LinearSegmentedColormap)
self.assertIsInstance(colormap, Colormap)
self.assertEqual("Reds", colormap.cm_name)
self.assertEqual("node", colormap.cm_type)
self.assertEqual("continuous", colormap.cm_type)
self.assertEqual("Sequential", colormap.cat_name)
self.assertIsNone(colormap.values)

Expand Down Expand Up @@ -306,7 +306,7 @@ def setUp(self) -> None:
def test_names(self):
self.assertEqual("Diverging", self.colormap.cat_name)
self.assertEqual("coolwarm", self.colormap.cm_name)
self.assertEqual("node", self.colormap.cm_type)
self.assertEqual("continuous", self.colormap.cm_type)

def test_cmap(self):
cmap = self.colormap.cmap
Expand Down
2 changes: 1 addition & 1 deletion xcube/core/tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ def compute_rgba_tile(

with measure_time("Encoding tile as RGBA image"):
var_tile, value_range = var_tiles[0], value_ranges[0]
if colormap.cm_type == "key":
if colormap.cm_type == "categorical":
assert isinstance(colormap.values, list)
norm = matplotlib.colors.BoundaryNorm(
colormap.values, ncolors=cmap.N, clip=False
Expand Down
22 changes: 12 additions & 10 deletions xcube/util/cmaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from PIL import Image

from xcube.constants import LOG
from xcube.util.assertions import assert_instance, assert_given
from xcube.util.assertions import assert_instance, assert_given, assert_in

try:
# noinspection PyPackageRequirements
Expand Down Expand Up @@ -228,8 +228,12 @@ def __init__(
norm: Optional[matplotlib.colors.Normalize] = None,
values: Optional[Sequence[Union[int, float]]] = None,
):
assert_instance(cm_name, str)
if cm_type is None:
cm_type = "continuous"
assert_in(cm_type, ("continuous", "stepwise", "categorical"))
self._cm_name = cm_name
self._cm_type = cm_type or "node"
self._cm_type = cm_type or "continuous"
self._cat_name = cat_name
self._cmap = cmap
self._cmap_reversed = cmap_reversed
Expand All @@ -246,7 +250,7 @@ def cm_name(self) -> str:

@property
def cm_type(self) -> str:
"""The colormap type, always one of "node", "bound", "key"."""
"""The colormap type, always one of "continuous", "stepwise", "categorical"."""
return self._cm_type

@property
Expand Down Expand Up @@ -464,16 +468,15 @@ def _register_ocm_cmaps(self):

def parse_cm_code(cm_code: str) -> tuple[str, Optional[Colormap]]:
# Note, if we get performance issues here, we should
# cache cm_code -> colormap
values: Optional[list[Union[int, float]]] = None
# cache cm_code -> colormap. Currently, parsing takes less than 50 micros
try:
user_color_map: dict[str, Any] = json.loads(cm_code)
cm_name = user_color_map["name"]
cm_items = user_color_map["colors"]
cm_type = user_color_map.get("type", "node")
cm_type = user_color_map.get("type", "continuous")
cm_base_name, _, _ = parse_cm_name(cm_name)
n = len(cm_items)
if cm_type == "key":
if cm_type == "categorical":
values: list[int] = []
colors: list[Union[str, tuple[float, ...]]] = []
bad = 0, 0, 0, 0
Expand All @@ -490,16 +493,15 @@ def parse_cm_code(cm_code: str) -> tuple[str, Optional[Colormap]]:
colors.append(bad)
cmap = matplotlib.colors.ListedColormap(colors, name=cm_base_name)
cmap.set_extremes(bad=bad, under=bad, over=bad)
print(">>>>>>>>>>>> categorical cmap", cmap)
else: # cm_type == "bound" or cm_type == "node"
else: # cm_type == "continuous" or cm_type == "stepwise"
values, colors = zip(*cm_items)
vmin = cm_items[0][0]
vmax = cm_items[-1][0]
if vmin != 0 or vmax != 1:
# Normalize values of cm_items between 0 and 1
norm_values = (np.array(values) - vmin) / (vmax - vmin)
cm_items = list(zip(norm_values, colors))
if cm_type == "bound":
if cm_type == "stepwise":
# Turn cm_items into discrete step function
stepwise_cm_items = []
for i, (value, color) in enumerate(cm_items[0:-1]):
Expand Down

0 comments on commit 6c8552a

Please sign in to comment.