Py-ART Basics
Overview
Within this notebook, we will cover:
General overview of Py-ART and its functionality
Reading data using Py-ART
An overview of the
pyart.Radar
objectCreate a Plot of our Radar Data
Prerequisites
Concepts |
Importance |
Notes |
---|---|---|
Helpful |
Basic features |
|
Helpful |
Basic plotting |
|
Helpful |
Basic arrays |
Time to learn: 15 minutes
Imports
import os
import warnings
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import pyart
warnings.filterwarnings('ignore')
## You are using the Python ARM Radar Toolkit (Py-ART), an open source
## library for working with weather radar data. Py-ART is partly
## supported by the U.S. Department of Energy as part of the Atmospheric
## Radiation Measurement (ARM) Climate Research Facility, an Office of
## Science user facility.
##
## If you use this software to prepare a publication, please cite:
##
## JJ Helmus and SM Collis, JORS 2016, doi: 10.5334/jors.119
An Overview of Py-ART
History of the Py-ART
Development began to address the needs of ARM with the acquisition of a number of new scanning cloud and precipitation radar as part of the American Recovery Act.
The project has since expanded to work with a variety of weather radars and a wider user base including radar researchers and climate modelers.
The software has been released on GitHub as open source software under a BSD license. Runs on Linux, OS X. It also runs on Windows with more limited functionality.
What can PyART Do?
Py-ART can be used for a variety of tasks from basic plotting to more complex processing pipelines. Specific uses for Py-ART include:
Reading radar data in a variety of file formats.
Creating plots and visualization of radar data.
Correcting radar moments while in antenna coordinates, such as:
Doppler unfolding/de-aliasing.
Attenuation correction.
Phase processing using a Linear Programming method.
Mapping data from one or multiple radars onto a Cartesian grid.
Performing retrievals.
Writing radial and Cartesian data to NetCDF files.
Reading in Data Using Py-ART
Reading data in using pyart.io.read
When reading in a radar file, we use the pyart.io.read
module.
pyart.io.read
can read a variety of different radar formats, such as Cf/Radial, LASSEN, and more.
The documentation on what formats can be read by Py-ART can be found here:
For most file formats listed on the page, using pyart.io.read
should suffice since Py-ART has the ability to automatically detect the file format.
Let’s check out what arguments arguments pyart.io.read()
takes in!
pyart.io.read?
Signature: pyart.io.read(filename, use_rsl=False, **kwargs)
Docstring:
Read a radar file and return a radar object.
Additional parameters are passed to the underlying read_* function.
Parameters
----------
filename : str
Name of radar file to read.
use_rsl : bool
True will use the TRMM RSL library to read files which are supported
both natively and by RSL. False will choose the native read function.
RSL will always be used to read a file if it is not supported
natively.
Other Parameters
-------------------
field_names : dict, optional
Dictionary mapping file data type names to radar field names. If a
data type found in the file does not appear in this dictionary or has
a value of None it will not be placed in the radar.fields dictionary.
A value of None, the default, will use the mapping defined in the
metadata configuration file.
additional_metadata : dict of dicts, optional
Dictionary of dictionaries to retrieve metadata from during this read.
This metadata is not used during any successive file reads unless
explicitly included. A value of None, the default, will not
introduct any addition metadata and the file specific or default
metadata as specified by the metadata configuration file will be used.
file_field_names : bool, optional
True to use the file data type names for the field names. If this
case the field_names parameter is ignored. The field dictionary will
likely only have a 'data' key, unless the fields are defined in
`additional_metadata`.
exclude_fields : list or None, optional
List of fields to exclude from the radar object. This is applied
after the `file_field_names` and `field_names` parameters.
delay_field_loading : bool
True to delay loading of field data from the file until the 'data'
key in a particular field dictionary is accessed. In this case
the field attribute of the returned Radar object will contain
LazyLoadDict objects not dict objects. Not all file types support this
parameter.
Returns
-------
radar : Radar
Radar object. A TypeError is raised if the format cannot be
determined.
File: ~/mambaforge/envs/arm-summer-school-2024-dev/lib/python3.11/site-packages/pyart/io/auto_read.py
Type: function
Let’s use a sample data file from pyart
- which is cfradial format.
When we read this in, we get a pyart.Radar
object!
file = "../data/cacti/radar/corcsapr2cmacppiM1.c1.20190125.200003.nc"
radar = pyart.io.read(file)
radar
<pyart.core.radar.Radar at 0x307b5f450>
Investigate the pyart.Radar
object
Within this pyart.Radar
object object are the actual data fields.
This is where data such as reflectivity and velocity are stored.
To see what fields are present we can add the fields and keys additions to the variable where the radar object is stored.
list(radar.fields)
['attenuation_corrected_reflectivity_h', 'corrected_velocity']
Extract the array for reflectivity values
There is a field for reflectivity, that has been quality controlled!
reflectivity = radar.fields["attenuation_corrected_reflectivity_h"]["data"]
Lets’ check the size of this array…
reflectivity
masked_array(
data=[[1.4373915195465088, 4.326587677001953, -8.80718994140625, ...,
-3.638805627822876, -1.9264719486236572, -12.983088493347168],
[1.1647518873214722, 3.245835781097412, 5.7800116539001465, ...,
-2.2795302867889404, -13.718626976013184, -4.739171981811523],
[2.816281318664551, 7.137325286865234, 13.460996627807617, ...,
-4.9431610107421875, -4.650906562805176, -5.725773811340332],
...,
[-2.6561262607574463, -3.501505136489868, -3.9879415035247803,
..., --, --, -6.141598701477051],
[-3.0994107723236084, -4.078167915344238, -3.2641713619232178,
..., -6.894789695739746, --, --],
[-2.507056951522827, 1.2157492637634277, -3.7937591075897217,
..., --, -7.004630088806152, -9.389737129211426]],
mask=[[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
...,
[False, False, False, ..., True, True, False],
[False, False, False, ..., False, True, True],
[False, False, False, ..., True, False, False]],
fill_value=-32767.0,
dtype=float32)
This reflectivity data array, numpy array, is a two-dimensional array with dimensions:
Gates (number of samples away from the radar)
Rays (direction around the radar)
print(radar.nrays, radar.ngates)
5407 1100
If we wanted to look the 300th ray, at the second gate, we would use something like the following:
print(reflectivity[300, 2])
4.65807
Plotting our Radar Data
An Overview of Py-ART Plotting Utilities
Now that we have loaded the data and inspected it, the next logical thing to do is to visualize the data! Py-ART’s visualization functionality is done through the objects in the pyart.graph module.
In Py-ART there are 4 primary visualization classes in pyart.graph:
Plotting grid data
Use the RadarMapDisplay with our data
For the this example, we will be using RadarMapDisplay
, using Cartopy to deal with geographic coordinates.
We start by creating a figure first.
fig = plt.figure(figsize=[10, 10])
<Figure size 1000x1000 with 0 Axes>
Once we have a figure, let’s add our RadarDisplay
fig = plt.figure(figsize=[10, 10])
display = pyart.graph.RadarDisplay(radar)
<Figure size 1000x1000 with 0 Axes>
Adding our map display without specifying a field to plot won’t do anything we need to specifically add a field to field using .plot_ppi()
display.plot_ppi('attenuation_corrected_reflectivity_h')
By default, it will plot the elevation scan, the the default colormap from Matplotlib
… let’s customize!
We add the following arguements:
sweep=3
- The fourth elevation scan (since we are using Python indexing)vmin=-20
- Minimum value for our plotted field/colorbarvmax=60
- Maximum value for our plotted field/colorbarprojection=ccrs.PlateCarree()
- Cartopy latitude/longitude coordinate systemcmap='pyart_HomeyerRainbow'
- Colormap to use, selecting one provided by PyART
fig = plt.figure(figsize=[8, 6])
display = pyart.graph.RadarDisplay(radar)
display.plot_ppi('attenuation_corrected_reflectivity_h',
sweep=3,
vmin=-20,
vmax=60,
cmap='pyart_HomeyerRainbow')
plt.show()
You can change many parameters in the graph by changing the arguments to plot_ppi. As you can recall from earlier. simply view these arguments in a Jupyter notebook by typing:
display.plot_ppi?
Signature:
display.plot_ppi(
field,
sweep=0,
mask_tuple=None,
vmin=None,
vmax=None,
norm=None,
cmap=None,
mask_outside=False,
title=None,
title_flag=True,
axislabels=(None, None),
axislabels_flag=True,
colorbar_flag=True,
colorbar_label=None,
colorbar_orient='vertical',
edges=True,
gatefilter=None,
filter_transitions=True,
ax=None,
fig=None,
ticks=None,
ticklabs=None,
raster=False,
title_datetime_format=None,
title_use_sweep_time=True,
**kwargs,
)
Docstring:
Plot a PPI.
Additional arguments are passed to Matplotlib's pcolormesh function.
Parameters
----------
field : str
Field to plot.
sweep : int, optional
Sweep number to plot.
Other Parameters
----------------
mask_tuple : (str, float)
Tuple containing the field name and value below which to mask
field prior to plotting, for example to mask all data where
NCP < 0.5 set mask_tuple to ['NCP', 0.5]. None performs no masking.
vmin : float
Luminance minimum value, None for default value.
Parameter is ignored is norm is not None.
vmax : float
Luminance maximum value, None for default value.
Parameter is ignored is norm is not None.
norm : Normalize or None, optional
matplotlib Normalize instance used to scale luminance data. If not
None the vmax and vmin parameters are ignored. If None, vmin and
vmax are used for luminance scaling.
cmap : str or None
Matplotlib colormap name. None will use the default colormap for
the field being plotted as specified by the Py-ART configuration.
mask_outside : bool
True to mask data outside of vmin, vmax. False performs no
masking.
title : str
Title to label plot with, None to use default title generated from
the field and sweep parameters. Parameter is ignored if title_flag
is False.
title_datetime_format : str
Format of datetime in the title (using strftime format).
title_use_sweep_time : bool
True for the current sweep's beginning time to be used for the
title. False for the radar's beginning time.
title_flag : bool
True to add a title to the plot, False does not add a title.
axislabels : (str, str)
2-tuple of x-axis, y-axis labels. None for either label will use
the default axis label. Parameter is ignored if axislabels_flag is
False.
axislabels_flag : bool
True to add label the axes, False does not label the axes.
colorbar_flag : bool
True to add a colorbar with label to the axis. False leaves off
the colorbar.
colorbar_label : str
Colorbar label, None will use a default label generated from the
field information.
colorbar_orient : 'vertical' or 'horizontal'
Colorbar orientation.
ticks : array
Colorbar custom tick label locations.
ticklabs : array
Colorbar custom tick labels.
edges : bool
True will interpolate and extrapolate the gate edges from the
range, azimuth and elevations in the radar, treating these
as specifying the center of each gate. False treats these
coordinates themselves as the gate edges, resulting in a plot
in which the last gate in each ray and the entire last ray are not
plotted.
gatefilter : GateFilter
GateFilter instance. None will result in no gatefilter mask being
applied to data.
filter_transitions : bool
True to remove rays where the antenna was in transition between
sweeps from the plot. False will include these rays in the plot.
No rays are filtered when the antenna_transition attribute of the
underlying radar is not present.
ax : Axis
Axis to plot on. None will use the current axis.
fig : Figure
Figure to add the colorbar to. None will use the current figure.
raster : bool
False by default. Set to true to render the display as a raster
rather than a vector in call to pcolormesh. Saves time in plotting
high resolution data over large areas. Be sure to set the dpi
of the plot for your application if you save it as a vector format
(i.e., pdf, eps, svg).
File: ~/mambaforge/envs/arm-summer-school-2024-dev/lib/python3.11/site-packages/pyart/graph/radardisplay.py
Type: method
Challenge: Create a new map of your own!
Plot the
corrected_velocity
field with suitable minimum and maximum values, with a colorbar of your choosing.
Summary
Within this notebook, we covered the basics of working with radar data using pyart
, including:
Reading in a file using
pyart.io
Investigating the
Radar
objectVisualizing radar data using the
RadarDisplay
What’s Next
In the next few notebooks, we walk through gridding radar data, applying data cleaning methods, and advanced visualization methods!
Resources and References
Py-ART essentials links: