From 4c53c1ea8cbf9887edc3e6d4ecac48379e1f1765 Mon Sep 17 00:00:00 2001 From: Alex Morling Date: Sat, 14 Dec 2024 16:59:19 +0200 Subject: [PATCH 1/2] ignore transparent colors, not nan labels --- ecoscope/mapping/map.py | 3 +-- tests/test_ecomap.py | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ecoscope/mapping/map.py b/ecoscope/mapping/map.py index 020150fb..2f1a2790 100644 --- a/ecoscope/mapping/map.py +++ b/ecoscope/mapping/map.py @@ -256,10 +256,9 @@ def add_legend(self, labels: list | pd.Series, colors: list | pd.Series, **kwarg """ nans = None if isinstance(labels, pd.Series): - if pd.api.types.is_numeric_dtype(labels): - nans = np.argwhere(np.isnan(labels)) labels = labels.unique().tolist() if isinstance(colors, pd.Series): + nans = np.argwhere(colors == (0, 0, 0, 0)) colors = colors.unique().tolist() if len(labels) != len(colors): diff --git a/tests/test_ecomap.py b/tests/test_ecomap.py index e6f4d553..6b8886ec 100644 --- a/tests/test_ecomap.py +++ b/tests/test_ecomap.py @@ -2,7 +2,6 @@ import random import ee import geopandas as gpd -import numpy as np import pandas as pd import pytest import ecoscope @@ -89,16 +88,16 @@ def test_add_legend_series(): assert legend.colors == ["rgba(0, 0, 0, 1.0)", "rgba(255, 255, 255, 1.0)"] -def test_add_legend_series_with_nan(): +def test_add_legend_series_with_transparent(): m = EcoMap(default_widgets=False) m.add_legend( - labels=pd.Series([0, 1, np.nan, 5, np.nan]), + labels=pd.Series([1, 3, 0, 5, 0]), colors=pd.Series([(0, 0, 0, 255), (255, 255, 255, 255), (0, 0, 0, 0), (100, 100, 100, 255), (0, 0, 0, 0)]), ) assert len(m.deck_widgets) == 1 legend = m.deck_widgets[0] assert isinstance(legend, LegendWidget) - assert legend.labels == ["0.0", "1.0", "5.0"] + assert legend.labels == ["1", "3", "5"] assert legend.colors == ["rgba(0, 0, 0, 1.0)", "rgba(255, 255, 255, 1.0)", "rgba(100, 100, 100, 1.0)"] From 7f37e5addf337438b68c0c7c0056a931d2dba2ac Mon Sep 17 00:00:00 2001 From: Alex Morling Date: Sat, 14 Dec 2024 18:27:34 +0200 Subject: [PATCH 2/2] a better approach --- ecoscope/mapping/map.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/ecoscope/mapping/map.py b/ecoscope/mapping/map.py index 2f1a2790..12bd21cf 100644 --- a/ecoscope/mapping/map.py +++ b/ecoscope/mapping/map.py @@ -7,7 +7,7 @@ import numpy as np import pandas as pd import rasterio as rio -from ecoscope.base.utils import color_tuple_to_css +from ecoscope.base.utils import color_tuple_to_css, hex_to_rgba from io import BytesIO from typing import Dict, IO, List, Optional, TextIO, Union from pathlib import Path @@ -254,28 +254,27 @@ def add_legend(self, labels: list | pd.Series, colors: list | pd.Series, **kwarg style: dict Additional style params """ - nans = None if isinstance(labels, pd.Series): - labels = labels.unique().tolist() + labels = labels.tolist() if isinstance(colors, pd.Series): - nans = np.argwhere(colors == (0, 0, 0, 0)) - colors = colors.unique().tolist() + colors = colors.tolist() + labels = list(dict.fromkeys(labels)) + colors = list(dict.fromkeys(colors)) if len(labels) != len(colors): raise ValueError("Unique label and color values must be of equal number") - if nans is not None: - filtered_labels = [] - filtered_colors = [] - for index, value in enumerate(labels): - if index not in nans: - filtered_labels.append(labels[index]) - filtered_colors.append(colors[index]) - labels = filtered_labels - colors = filtered_colors - - widget_labels = [str(label) for label in labels] - widget_colors = [color_tuple_to_css(color) if isinstance(color, tuple) else color for color in colors] + filtered_labels = [] + filtered_colors = [] + for index, value in enumerate(colors): + if isinstance(value, str): + value = hex_to_rgba(value) + if len(value) == 4 and value[3] > 0: + filtered_labels.append(labels[index]) + filtered_colors.append(colors[index]) + + widget_labels = [str(label) for label in filtered_labels] + widget_colors = [color_tuple_to_css(color) if isinstance(color, tuple) else color for color in filtered_colors] self.add_widget(LegendWidget(labels=widget_labels, colors=widget_colors, **kwargs))