Source code for pyretlife.retrieval_plotting.color_handling

"""
This module contains the `RetrievalPlottingObject` class, which is the main
class used to generate plots of the pyretlife retrievals.
"""

__author__ = "Konrad, Alei, Molliere, Quanz"
__copyright__ = "Copyright 2022, Konrad, Alei, Molliere, Quanz"
__maintainer__ = "Björn S. Konrad, Eleonora Alei"
__email__ = "konradb@ethz.ch, elalei@phys.ethz.ch"
__status__ = "Development"

# -----------------------------------------------------------------------------
# IMPORTS
# -----------------------------------------------------------------------------
import matplotlib.colors as col
import numpy as np



# -----------------------------------------------------------------------------
# DEFINITIONS
# -----------------------------------------------------------------------------
[docs] def generate_quantile_color_levels(color,quantiles): """ Generate color levels for a set of provided quantiles based on a base color. This function calculates color levels corresponding to a set of quantiles, generating a smooth transition between the specified base color and its variations based on the quantile values. The color levels are represented as RGBA values, and the quantile thresholds are computed accordingly. :param color: The base color for the levels. It can be provided as a string (e.g., 'blue'), a hex code (e.g., '#0000FF'), or an RGB(A) tuple (e.g., (0, 0, 1, 1)). :type color: str or tuple :param quantiles: A list of quantile values for which to generate the corresponding color levels. Typically, this might include quantiles like [0.16, 0.5, 0.84] for a 68% confidence interval. :type quantiles: list :return: - `color_levels`: A numpy array of RGBA color levels corresponding to the specified quantiles. - `level_thresholds`: A list of the quantile thresholds for the color levels. - `N_levels`: The number of color levels calculated. :rtype: tuple :notes: - The color levels are generated by interpolating the base color across the quantile range. - The color transition is done in the RGB channels, and the alpha (opacity) is assumed to be constant for all levels. - This function is particularly useful for visualizing quantile-based data distributions in plots, such as in contour plots or heatmaps where different levels represent different quantile ranges. """ rgba_color = col.to_rgba(color) # Percentage of points in quantile range quantiles[i] to quantiles[-i-1] level_thresholds = list(2*np.array(quantiles[:int(len(quantiles)/2)]))+[1] N_levels = len(level_thresholds)-1 # Generate the color levels color_levels = np.ones((N_levels, 4)) for rgb_ind in range(3): color_levels[:, rgb_ind] = np.array([(i+1)/N_levels*rgba_color[rgb_ind]+(N_levels-i-1)/N_levels for i in range (N_levels)]) # Return information return color_levels, level_thresholds, N_levels
[docs] def generate_color_map_from_levels(Z,color_levels,level_thresholds): """ Generate a colormap for a 2D histogram based on specified percentage levels. This function creates a colormap by dividing the values in a 2D histogram (Z) into bins, identifying the bin ranges that correspond to specified percentage thresholds, and assigning colors from a predefined set of color levels to these bins. The function ensures that the colormap is scaled according to the cumulative counts in the histogram. :param Z: A 2D array representing the histogram counts. The values in `Z` represent the frequency or density in each bin of the histogram. :type Z: numpy.ndarray :param color_levels: A numpy array of RGBA color levels corresponding to the histogram bins. These colors will be applied to the histogram based on the percentage thresholds. :type color_levels: numpy.ndarray :param level_thresholds: A list of thresholds representing percentage levels that divide the cumulative distribution of the histogram. For example, [0.16, 0.5, 0.84] for a 68% confidence interval. :type level_thresholds: list :return: - `map`: The generated colormap. - `norm`: The normalization object used for mapping values to the colormap. - `levels`: A list of the bin counts that correspond to the specified threshold levels. :rtype: tuple :notes: - The function first sorts the histogram bins in ascending order and then identifies the bin values that correspond to the specified quantile thresholds. - The colormap is created using `col.from_levels_and_colors`, which requires predefined color levels. - The resulting colormap can be used in visualizations like contour plots or heatmaps where the color scale reflects the distribution of values in the 2D histogram. """ # Choose all bins with non-zero entries and sort them in ascending order level_counts = np.sort(Z.flatten())[np.where(np.sort(Z.flatten())>0)] # Identify the bin where the level counts exceeds the threshold values sum_level_counts = 0 threshold_ind = 0 levels = [] for i in range(len(level_counts)): sum_level_counts += level_counts[i] if sum_level_counts/np.sum(level_counts)>=level_thresholds[threshold_ind]: threshold_ind += 1 levels += [level_counts[i]] # Boundary case where the maximum is reached before the last level while len(levels) <= np.shape(color_levels)[0]: levels += [levels[-1]*10] # Generate the colormap map, norm = col.from_levels_and_colors(levels,color_levels) # Return the colormap return map, norm, levels
[docs] def generate_uniform_color_map(color_map): """ Generate a uniform colormap based on two input colors. This function creates a colormap that smoothly transitions between two specified colors. The colormap is uniformly distributed and can be used for visualizations where a smooth gradient between two colors is desired. :param color_map: A list or tuple containing two colors that define the start and end of the colormap. The colors can be specified in any valid format accepted by `matplotlib.colors.to_rgba`, such as a string (e.g., 'red', '#FF0000'), or a tuple of RGBA values (e.g., (1, 0, 0, 1)). :type color_map: list or tuple :return: A colormap object that smoothly transitions between the two specified colors. :rtype: `matplotlib.colors.ListedColormap` :notes: - The function creates a smooth gradient of 1000 color levels between the two input colors. - The resulting colormap can be used for visualizations such as heatmaps or contour plots where a uniform color gradient is needed. - The input colors are expected to be in a format compatible with `matplotlib.colors.to_rgba` (e.g., hex, named colors). """ # Convert to colors to RGB c1 = col.to_rgba(color_map[0]) c2 = col.to_rgba(color_map[1]) # Generate the levels levels = np.linspace(0,1,1000) # Generate the color levels color_levels = np.ones((999, 4)) for rgb_ind in range(3): color_levels[:, rgb_ind] = c1[rgb_ind]*(1-levels[1:])+c2[rgb_ind]*levels[:-1] # Return the colormap return col.from_levels_and_colors(levels,color_levels)[0]