Plot precipitation using custom colormap#

This tutorial shows how to plot data using a custom colormap with a specific range of precipitation values.

import os
from datetime import datetime
import matplotlib.pyplot as plt

import pysteps
from pysteps import io, rcparams
from pysteps.utils import conversion
from pysteps.visualization import plot_precip_field
from pysteps.datasets import download_pysteps_data, create_default_pystepsrc

Download the data if it is not available#

The following code block downloads datasets from the pysteps-data repository if it is not available on the disk. The dataset is used to demonstrate the plotting of precipitation data using a custom colormap.

# Check if the pysteps-data repository is available (it would be pysteps-data in pysteps)
# Implies that you are running this script from the `pysteps/examples` folder

if not os.path.exists(rcparams.data_sources["mrms"]["root_path"]):
    download_pysteps_data("pysteps_data")
    config_file_path = create_default_pystepsrc("pysteps_data")
    print(f"Configuration file has been created at {config_file_path}")

Read precipitation field#

First thing, load a frame from Multi-Radar Multi-Sensor dataset and convert it to precipitation rate in mm/h.

# Define the dataset and the date for which you want to load data
data_source = pysteps.rcparams.data_sources["mrms"]
date = datetime(2019, 6, 10, 0, 2, 0)  # Example date

# Extract the parameters from the data source
root_path = data_source["root_path"]
path_fmt = data_source["path_fmt"]
fn_pattern = data_source["fn_pattern"]
fn_ext = data_source["fn_ext"]
importer_name = data_source["importer"]
importer_kwargs = data_source["importer_kwargs"]
timestep = data_source["timestep"]

# Find the frame in the archive for the specified date
fns = io.find_by_date(
    date, root_path, path_fmt, fn_pattern, fn_ext, timestep, num_prev_files=1
)

# Read the frame from the archive
importer = io.get_method(importer_name, "importer")
R, _, metadata = io.read_timeseries(fns, importer, **importer_kwargs)

# Convert the reflectivity data to rain rate
R, metadata = conversion.to_rainrate(R, metadata)

# Plot the first rainfall field from the loaded data
plt.figure(figsize=(10, 5), dpi=300)
plt.axis("off")
plot_precip_field(R[0, :, :], geodata=metadata, axis="off")

plt.tight_layout()
plt.show()
plot custom precipitation range
/home/docs/checkouts/readthedocs.org/user_builds/pysteps/envs/latest/lib/python3.10/site-packages/pysteps/visualization/utils.py:439: UserWarning: cartopy package is required for the get_geogrid function but it is not installed. Ignoring geographical information.
  warnings.warn(

Define the custom colormap#

Assume that the default colormap does not represent the precipitation values in the desired range. In this case, you can define a custom colormap that will be used to plot the precipitation data and pass the class instance to the plot_precip_field function.

It essential for the custom colormap to have the following attributes:

  • cmap: The colormap object.

  • norm: The normalization object.

  • clevs: The color levels for the colormap.

plot_precip_field can handle each of the classes defined in the matplotlib.colors https://matplotlib.org/stable/api/colors_api.html#colormaps There must be as many colors in the colormap as there are levels in the color levels.

# Define the custom colormap

from matplotlib import colors


class ColormapConfig:
    def __init__(self):
        self.cmap = None
        self.norm = None
        self.clevs = None

        self.build_colormap()

    def build_colormap(self):
        # Define the colormap boundaries and colors
        # color_list = ['lightgrey', 'lightskyblue', 'blue', 'yellow', 'orange', 'red', 'darkred']
        color_list = ["blue", "navy", "yellow", "orange", "green", "brown", "red"]

        self.clevs = [0.1, 0.5, 1.5, 2.5, 4, 6, 10]  # mm/hr

        # Create a ListedColormap object with the defined colors
        self.cmap = colors.ListedColormap(color_list)
        self.cmap.name = "Custom Colormap"

        # Set the color for values above the maximum level
        self.cmap.set_over("darkmagenta")
        # Set the color for values below the minimum level
        self.cmap.set_under("none")
        # Set the color for missing values
        self.cmap.set_bad("gray", alpha=0.5)

        # Create a BoundaryNorm object to normalize the data values to the colormap boundaries
        self.norm = colors.BoundaryNorm(self.clevs, self.cmap.N)


# Create an instance of the ColormapConfig class
config = ColormapConfig()

# Plot the precipitation field using the custom colormap
plt.figure(figsize=(10, 5), dpi=300)
plt.axis("off")
plot_precip_field(R[0, :, :], geodata=metadata, axis="off", colormap_config=config)

plt.tight_layout()
plt.show()
plot custom precipitation range
/home/docs/checkouts/readthedocs.org/user_builds/pysteps/envs/latest/lib/python3.10/site-packages/pysteps/visualization/utils.py:439: UserWarning: cartopy package is required for the get_geogrid function but it is not installed. Ignoring geographical information.
  warnings.warn(

Total running time of the script: (0 minutes 4.027 seconds)

Gallery generated by Sphinx-Gallery