-
Notifications
You must be signed in to change notification settings - Fork 173
/
Copy pathplot_custom_precipitation_range.py
143 lines (110 loc) · 4.81 KB
/
plot_custom_precipitation_range.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/env python
"""
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()
###############################################################################
# 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()