Module geoengine.colorizer
This module is used to generate geoengine compatible color map definitions as a json string.
Expand source code
"""This module is used to generate geoengine compatible color map definitions as a json string."""
import json
from typing import Tuple
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from matplotlib.cm import ScalarMappable
class Colorizer():
"""This class is used to generate geoengine compatible color map definitions as a json string."""
# pylint: disable=too-few-public-methods
def __init__(
self,
map_name: ListedColormap,
min_max: Tuple[int, int],
n_steps: int = 10,
default_color: Tuple[int, int, int, int] = (0, 0, 0, 0),
no_data_color: Tuple[int, int, int, int] = (0, 0, 0, 0)):
"""Initialize the colorizer."""
# pylint: disable=too-many-arguments
# assert correct parameters are given
if not isinstance(map_name, ListedColormap):
if map_name not in plt.colormaps():
raise AssertionError(
"The given name is not a valid matplotlib colormap. Valid names are: "
"['magma', 'inferno', 'plasma', 'viridis', 'cividis', 'twilight', 'twilight_shifted',"
"'turbo', 'Blues', 'BrBG', 'BuGn', 'BuPu', 'CMRmap', 'GnBu', 'Greens', 'Greys', 'OrRd', "
"'Oranges', 'PRGn', 'PiYG', 'PuBu', 'PuBuGn', 'PuOr', 'PuRd', 'Purples', 'RdBu', 'RdGy', "
"'RdPu', 'RdYlBu', 'RdYlGn', 'Reds', 'Spectral', 'Wistia', 'YlGn', 'YlGnBu', 'YlOrBr', "
"'YlOrRd', 'afmhot', 'autumn', 'binary', 'bone', 'brg', 'bwr', 'cool', 'coolwarm', "
"'copper', 'cubehelix', 'flag', 'gist_earth', 'gist_gray', 'gist_heat', 'gist_ncar', "
"'gist_rainbow', 'gist_stern', 'gist_yarg', 'gnuplot', 'gnuplot2', 'gray', 'hot', "
"'hsv', 'jet', 'nipy_spectral', 'ocean', 'pink', 'prism', 'rainbow', 'seismic', 'spring', "
"'summer', 'terrain', 'winter', 'Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', "
"'Set1', 'Set2', 'Set3', 'tab10', 'tab20', 'tab20b', 'tab20c', 'magma_r', 'inferno_r', "
"'plasma_r', 'viridis_r', 'cividis_r', 'twilight_r', 'twilight_shifted_r', 'turbo_r', "
"'Blues_r', 'BrBG_r', 'BuGn_r', 'BuPu_r', 'CMRmap_r', 'GnBu_r', 'Greens_r', 'Greys_r', "
"'OrRd_r', 'Oranges_r', 'PRGn_r', 'PiYG_r', 'PuBu_r', 'PuBuGn_r', 'PuOr_r', 'PuRd_r', "
"'Purples_r', 'RdBu_r', 'RdGy_r', 'RdPu_r', 'RdYlBu_r', 'RdYlGn_r', 'Reds_r', "
"'Spectral_r', 'Wistia_r', 'YlGn_r', 'YlGnBu_r', 'YlOrBr_r', 'YlOrRd_r', 'afmhot_r', "
"'autumn_r', 'binary_r', 'bone_r', 'brg_r', 'bwr_r', 'cool_r', 'coolwarm_r', 'copper_r', "
"'cubehelix_r', 'flag_r', 'gist_earth_r', 'gist_gray_r', 'gist_heat_r', 'gist_ncar_r', "
"'gist_rainbow_r', 'gist_stern_r', 'gist_yarg_r', 'gnuplot_r', 'gnuplot2_r', 'gray_r', "
"'hot_r', 'hsv_r', 'jet_r', 'nipy_spectral_r', 'ocean_r', 'pink_r', 'prism_r', "
"'rainbow_r', 'seismic_r', 'spring_r', 'summer_r', 'terrain_r', 'winter_r', 'Accent_r', "
"'Dark2_r', 'Paired_r', 'Pastel1_r', 'Pastel2_r', 'Set1_r', 'Set2_r', 'Set3_r', "
"'tab10_r', 'tab20_r', 'tab20b_r', 'tab20c_r']")
if n_steps < 2:
raise ValueError(f"n_steps must be greater than or equal to 2, got {n_steps} instead.")
if min_max[1] <= min_max[0]:
raise ValueError(f"min_max[1] must be greater than min_max[0], got {min_max[1]} and {min_max[0]}.")
if len(default_color) != 4:
raise ValueError(f"defaultColor must be a tuple of length 4, got {len(default_color)} instead.")
if len(no_data_color) != 4:
raise ValueError(f"noDataColor must be a tuple of length 4, got {len(no_data_color)} instead.")
if not all(0 <= elem < 256 for elem in no_data_color):
raise ValueError(f"noDataColor must be a RGBA color specification, got {no_data_color} instead.")
if not all(0 <= elem < 256 for elem in default_color):
raise ValueError(f"defaultColor must be a RGBA color specification, got {default_color} instead.")
self.__map_name = map_name
self.__min_max = min_max
self.__n_steps = n_steps
self.__default_color = default_color
self.__no_data_color = no_data_color
def to_query_string(self) -> str:
"""Generate a json dump that is compatible with the geoengine config protocol.
Args:
map_name (str): a name of a defined colormap.
n_steps (int): how many steps the colormap should have.
Returns:
str: Returns the geoengine compatible json configuration string.
"""
# get the map, and transform it to [0,255] values
colormap = ScalarMappable(cmap=self.__map_name).to_rgba(
np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps), bytes=True).tolist()
# if you want to remap the colors, you can do it here (e.g. cutting of the most extreme colors)
value_bounds = [
int(x) for x in np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps).tolist()
]
# generate color map steps for geoengine
breakpoints = [
{"value": value, "color": color} for (value, color) in zip(value_bounds, colormap)
]
# create the json string for geoengine
colorizer = "custom:" + json.dumps(
{
"type": "linearGradient",
"breakpoints": breakpoints,
"noDataColor": self.__no_data_color,
"defaultColor": self.__default_color,
}
)
return colorizer
Classes
class Colorizer (map_name: matplotlib.colors.ListedColormap, min_max: Tuple[int, int], n_steps: int = 10, default_color: Tuple[int, int, int, int] = (0, 0, 0, 0), no_data_color: Tuple[int, int, int, int] = (0, 0, 0, 0))
-
This class is used to generate geoengine compatible color map definitions as a json string.
Initialize the colorizer.
Expand source code
class Colorizer(): """This class is used to generate geoengine compatible color map definitions as a json string.""" # pylint: disable=too-few-public-methods def __init__( self, map_name: ListedColormap, min_max: Tuple[int, int], n_steps: int = 10, default_color: Tuple[int, int, int, int] = (0, 0, 0, 0), no_data_color: Tuple[int, int, int, int] = (0, 0, 0, 0)): """Initialize the colorizer.""" # pylint: disable=too-many-arguments # assert correct parameters are given if not isinstance(map_name, ListedColormap): if map_name not in plt.colormaps(): raise AssertionError( "The given name is not a valid matplotlib colormap. Valid names are: " "['magma', 'inferno', 'plasma', 'viridis', 'cividis', 'twilight', 'twilight_shifted'," "'turbo', 'Blues', 'BrBG', 'BuGn', 'BuPu', 'CMRmap', 'GnBu', 'Greens', 'Greys', 'OrRd', " "'Oranges', 'PRGn', 'PiYG', 'PuBu', 'PuBuGn', 'PuOr', 'PuRd', 'Purples', 'RdBu', 'RdGy', " "'RdPu', 'RdYlBu', 'RdYlGn', 'Reds', 'Spectral', 'Wistia', 'YlGn', 'YlGnBu', 'YlOrBr', " "'YlOrRd', 'afmhot', 'autumn', 'binary', 'bone', 'brg', 'bwr', 'cool', 'coolwarm', " "'copper', 'cubehelix', 'flag', 'gist_earth', 'gist_gray', 'gist_heat', 'gist_ncar', " "'gist_rainbow', 'gist_stern', 'gist_yarg', 'gnuplot', 'gnuplot2', 'gray', 'hot', " "'hsv', 'jet', 'nipy_spectral', 'ocean', 'pink', 'prism', 'rainbow', 'seismic', 'spring', " "'summer', 'terrain', 'winter', 'Accent', 'Dark2', 'Paired', 'Pastel1', 'Pastel2', " "'Set1', 'Set2', 'Set3', 'tab10', 'tab20', 'tab20b', 'tab20c', 'magma_r', 'inferno_r', " "'plasma_r', 'viridis_r', 'cividis_r', 'twilight_r', 'twilight_shifted_r', 'turbo_r', " "'Blues_r', 'BrBG_r', 'BuGn_r', 'BuPu_r', 'CMRmap_r', 'GnBu_r', 'Greens_r', 'Greys_r', " "'OrRd_r', 'Oranges_r', 'PRGn_r', 'PiYG_r', 'PuBu_r', 'PuBuGn_r', 'PuOr_r', 'PuRd_r', " "'Purples_r', 'RdBu_r', 'RdGy_r', 'RdPu_r', 'RdYlBu_r', 'RdYlGn_r', 'Reds_r', " "'Spectral_r', 'Wistia_r', 'YlGn_r', 'YlGnBu_r', 'YlOrBr_r', 'YlOrRd_r', 'afmhot_r', " "'autumn_r', 'binary_r', 'bone_r', 'brg_r', 'bwr_r', 'cool_r', 'coolwarm_r', 'copper_r', " "'cubehelix_r', 'flag_r', 'gist_earth_r', 'gist_gray_r', 'gist_heat_r', 'gist_ncar_r', " "'gist_rainbow_r', 'gist_stern_r', 'gist_yarg_r', 'gnuplot_r', 'gnuplot2_r', 'gray_r', " "'hot_r', 'hsv_r', 'jet_r', 'nipy_spectral_r', 'ocean_r', 'pink_r', 'prism_r', " "'rainbow_r', 'seismic_r', 'spring_r', 'summer_r', 'terrain_r', 'winter_r', 'Accent_r', " "'Dark2_r', 'Paired_r', 'Pastel1_r', 'Pastel2_r', 'Set1_r', 'Set2_r', 'Set3_r', " "'tab10_r', 'tab20_r', 'tab20b_r', 'tab20c_r']") if n_steps < 2: raise ValueError(f"n_steps must be greater than or equal to 2, got {n_steps} instead.") if min_max[1] <= min_max[0]: raise ValueError(f"min_max[1] must be greater than min_max[0], got {min_max[1]} and {min_max[0]}.") if len(default_color) != 4: raise ValueError(f"defaultColor must be a tuple of length 4, got {len(default_color)} instead.") if len(no_data_color) != 4: raise ValueError(f"noDataColor must be a tuple of length 4, got {len(no_data_color)} instead.") if not all(0 <= elem < 256 for elem in no_data_color): raise ValueError(f"noDataColor must be a RGBA color specification, got {no_data_color} instead.") if not all(0 <= elem < 256 for elem in default_color): raise ValueError(f"defaultColor must be a RGBA color specification, got {default_color} instead.") self.__map_name = map_name self.__min_max = min_max self.__n_steps = n_steps self.__default_color = default_color self.__no_data_color = no_data_color def to_query_string(self) -> str: """Generate a json dump that is compatible with the geoengine config protocol. Args: map_name (str): a name of a defined colormap. n_steps (int): how many steps the colormap should have. Returns: str: Returns the geoengine compatible json configuration string. """ # get the map, and transform it to [0,255] values colormap = ScalarMappable(cmap=self.__map_name).to_rgba( np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps), bytes=True).tolist() # if you want to remap the colors, you can do it here (e.g. cutting of the most extreme colors) value_bounds = [ int(x) for x in np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps).tolist() ] # generate color map steps for geoengine breakpoints = [ {"value": value, "color": color} for (value, color) in zip(value_bounds, colormap) ] # create the json string for geoengine colorizer = "custom:" + json.dumps( { "type": "linearGradient", "breakpoints": breakpoints, "noDataColor": self.__no_data_color, "defaultColor": self.__default_color, } ) return colorizer
Methods
def to_query_string(self) ‑> str
-
Generate a json dump that is compatible with the geoengine config protocol.
Args
map_name
:str
- a name of a defined colormap.
n_steps
:int
- how many steps the colormap should have.
Returns
str
- Returns the geoengine compatible json configuration string.
Expand source code
def to_query_string(self) -> str: """Generate a json dump that is compatible with the geoengine config protocol. Args: map_name (str): a name of a defined colormap. n_steps (int): how many steps the colormap should have. Returns: str: Returns the geoengine compatible json configuration string. """ # get the map, and transform it to [0,255] values colormap = ScalarMappable(cmap=self.__map_name).to_rgba( np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps), bytes=True).tolist() # if you want to remap the colors, you can do it here (e.g. cutting of the most extreme colors) value_bounds = [ int(x) for x in np.linspace(self.__min_max[0], self.__min_max[1], self.__n_steps).tolist() ] # generate color map steps for geoengine breakpoints = [ {"value": value, "color": color} for (value, color) in zip(value_bounds, colormap) ] # create the json string for geoengine colorizer = "custom:" + json.dumps( { "type": "linearGradient", "breakpoints": breakpoints, "noDataColor": self.__no_data_color, "defaultColor": self.__default_color, } ) return colorizer