{ "cells": [ { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "# Py-ART Basics\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Overview\n", " \n", "Within this notebook, we will cover:\n", "\n", "1. General overview of Py-ART and its functionality\n", "1. Reading data using Py-ART\n", "1. An overview of the `pyart.Radar` object\n", "1. Create a Plot of our Radar Data\n" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Prerequisites\n", "| Concepts | Importance | Notes |\n", "| --- | --- | --- |\n", "| [Intro to Cartopy](https://foundations.projectpythia.org/core/cartopy/cartopy.html) | Helpful | Basic features |\n", "| [Matplotlib Basics](https://foundations.projectpythia.org/core/matplotlib/matplotlib-basics.html) | Helpful | Basic plotting |\n", "| [NumPy Basics](https://foundations.projectpythia.org/core/numpy/numpy-basics.html) | Helpful | Basic arrays |\n", "\n", "- **Time to learn**: 45 minutes\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import os\n", "import warnings\n", "\n", "import cartopy.crs as ccrs\n", "import matplotlib.pyplot as plt\n", "\n", "\n", "import pyart\n", "from pyart.testing import get_test_data\n", "\n", "warnings.filterwarnings('ignore')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## An Overview of Py-ART" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### History of the Py-ART\n", "\n", " * Development began to address the needs of ARM with the acquisition of a number of\n", " new scanning cloud and precipitation radar as part of the American Recovery Act.\n", " * The project has since expanded to work with a variety of weather radars and a wider user\n", " base including radar researchers and climate modelers.\n", " * The software has been released on GitHub as open source software under a BSD license.\n", " Runs on Linux, OS X. It also runs on Windows with more limited functionality.\n", "\n", "### What can PyART Do?\n", "\n", "Py-ART can be used for a variety of tasks from basic plotting to more complex\n", "processing pipelines. Specific uses for Py-ART include:\n", "\n", " * Reading radar data in a variety of file formats.\n", " * Creating plots and visualization of radar data.\n", " * Correcting radar moments while in antenna coordinates, such as:\n", " * Doppler unfolding/de-aliasing.\n", " * Attenuation correction.\n", " * Phase processing using a Linear Programming method.\n", " * Mapping data from one or multiple radars onto a Cartesian grid.\n", " * Performing retrievals.\n", " * Writing radial and Cartesian data to NetCDF files." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading in Data Using Py-ART" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reading data in using `pyart.io.read`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When reading in a radar file, we use the `pyart.io.read` module.\n", "\n", "`pyart.io.read` can read a variety of different radar formats, such as Cf/Radial, LASSEN, and more. \n", "The documentation on what formats can be read by Py-ART can be found here:\n", "\n", "* [Py-ART IO Documentation](https://arm-doe.github.io/pyart/API/generated/pyart.io.html)\n", "\n", "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.\n", "\n", "Let's check out what arguments arguments `pyart.io.read()` takes in!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "pyart.io.read?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's use a sample data file from `pyart` - which is [**cfradial** format](https://github.com/NCAR/CfRadial).\n", "\n", "When we read this in, we get a [`pyart.Radar` object](https://arm-doe.github.io/pyart/API/generated/pyart.core.Radar.html#pyart.core.Radar)!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "file = get_test_data('swx_20120520_0641.nc')\n", "radar = pyart.io.read(file)\n", "radar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Investigate the [`pyart.Radar` object](https://arm-doe.github.io/pyart/API/generated/pyart.core.Radar.html#pyart.core.Radar)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Within this [`pyart.Radar` object](https://arm-doe.github.io/pyart/API/generated/pyart.core.Radar.html#pyart.core.Radar) object are the actual data fields.\n", "\n", "This is where data such as reflectivity and velocity are stored.\n", "\n", "To see what fields are present we can add the fields and keys additions to the variable where the radar object is stored." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "radar.fields.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Extract a sample data field" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The fields are stored in a dictionary, each containing coordinates, units and more.\n", "All can be accessed by just adding the fields addition to the radar object variable.\n", "\n", "For an individual field, we add a string in brackets after the fields addition to see\n", "the contents of that field.\n", "\n", "Let's take a look at `'corrected_reflectivity_horizontal'`, which is a common field to investigate." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "print(radar.fields['corrected_reflectivity_horizontal'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can go even further in the dictionary and access the actual reflectivity data.\n", "\n", "We use add `'data'` at the end, which will extract the **data array** (which is a masked numpy array) from the dictionary." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "reflectivity = radar.fields['corrected_reflectivity_horizontal']['data']\n", "print(type(reflectivity), reflectivity)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets' check the size of this array..." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "reflectivity.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This reflectivity data array, numpy array, is a two-dimensional array with dimensions:\n", "- Gates (number of samples away from the radar)\n", "- Rays (direction around the radar)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "print(radar.nrays, radar.ngates)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we wanted to look the 300th ray, at the second gate, we would use something like the following:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "print(reflectivity[300, 2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting our Radar Data" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### An Overview of Py-ART Plotting Utilities\n", "\n", "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](https://arm-doe.github.io/pyart/API/generated/pyart.graph.html) module.\n", "\n", "In Py-ART there are 4 primary visualization classes in pyart.graph:\n", "\n", "* [RadarDisplay](https://arm-doe.github.io/pyart/API/generated/pyart.graph.RadarDisplay.html)\n", "* [RadarMapDisplay](https://arm-doe.github.io/pyart/API/generated/pyart.graph.RadarMapDisplay.html)\n", "* [AirborneRadarDisplay](https://arm-doe.github.io/pyart/API/generated/pyart.graph.AirborneRadarDisplay.html)\n", "\n", "Plotting grid data\n", "* [GridMapDisplay](https://arm-doe.github.io/pyart/API/generated/pyart.graph.GridMapDisplay.html)\n", "\n", "### Use the [RadarMapDisplay](https://arm-doe.github.io/pyart/API/generated/pyart.graph.RadarMapDisplay.html) with our data\n", "\n", "For the this example, we will be using `RadarMapDisplay`, using Cartopy to deal with geographic coordinates.\n", "\n", "\n", "We start by creating a figure first." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[10, 10])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once we have a figure, let's add our `RadarMapDisplay`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[10, 10])\n", "display = pyart.graph.RadarMapDisplay(radar)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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_map()`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "display.plot_ppi_map('corrected_reflectivity_horizontal')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, it will plot the elevation scan, the the default colormap from `Matplotlib`... let's customize!\n", "\n", "We add the following arguements:\n", "- `sweep=3` - The fourth elevation scan (since we are using Python indexing)\n", "- `vmin=-20` - Minimum value for our plotted field/colorbar\n", "- `vmax=60` - Maximum value for our plotted field/colorbar\n", "- `projection=ccrs.PlateCarree()` - Cartopy latitude/longitude coordinate system\n", "- `cmap='pyart_HomeyerRainbow'` - Colormap to use, selecting one provided by PyART " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[12, 12])\n", "display = pyart.graph.RadarMapDisplay(radar)\n", "display.plot_ppi_map('corrected_reflectivity_horizontal',\n", " sweep=3,\n", " vmin=-20,\n", " vmax=60,\n", " projection=ccrs.PlateCarree(),\n", " cmap='pyart_HomeyerRainbow')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can change many parameters in the graph by changing the arguments to plot_ppi_map. As you can recall from earlier. simply view these arguments in a Jupyter notebook by typing:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "display.plot_ppi_map?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, let's change the colormap to something different" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[12, 12])\n", "display = pyart.graph.RadarMapDisplay(radar)\n", "display.plot_ppi_map('corrected_reflectivity_horizontal',\n", " sweep=3,\n", " vmin=-20,\n", " vmax=60,\n", " projection=ccrs.PlateCarree(),\n", " cmap='pyart_Carbone42')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or, let's view a different elevation scan! To do this, change the sweep parameter in the plot_ppi_map function." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[12, 12])\n", "display = pyart.graph.RadarMapDisplay(radar)\n", "display.plot_ppi_map('corrected_reflectivity_horizontal',\n", " sweep=0,\n", " vmin=-20,\n", " vmax=60,\n", " projection=ccrs.PlateCarree(),\n", " cmap='pyart_Carbone42')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's take a look at a different field - for example, correlation coefficient (`corr_coeff`)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "fig = plt.figure(figsize=[12, 12])\n", "display = pyart.graph.RadarMapDisplay(radar)\n", "display.plot_ppi_map('copol_coeff',\n", " sweep=0,\n", " vmin=0.8,\n", " vmax=1.,\n", " projection=ccrs.PlateCarree(),\n", " cmap='pyart_Carbone42')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## Summary\n", "Within this notebook, we covered the basics of working with radar data using `pyart`, including:\n", "- Reading in a file using `pyart.io`\n", "- Investigating the `Radar` object\n", "- Visualizing radar data using the `RadarMapDisplay`\n", "\n", "### What's Next\n", "In the next few notebooks, we walk through gridding radar data, applying data cleaning methods, and advanced visualization methods!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Resources and References\n", "Py-ART essentials links:\n", "\n", "* [Landing page](arm-doe.github.io/pyart/)\n", "* [Examples](https://arm-doe.github.io/pyart/examples/index.html)\n", "* [Source Code](github.com/ARM-DOE/pyart)\n", "* [Mailing list](groups.google.com/group/pyart-users/)\n", "* [Issue Tracker](github.com/ARM-DOE/pyart/issues)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 August 2022 Environment", "language": "python", "name": "aug22" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.5" } }, "nbformat": 4, "nbformat_minor": 4 }