{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "9ca177b5", "metadata": {}, "source": [ "# Radar Plan Position Indicator (PPI) in 3D\n", "\n", "This is adopted from [this example](https://docs.openradarscience.org/projects/xradar/en/stable/notebooks/plot-ppi.html) to visualize sweeps of radar data as a 3D volume. The 3D visualization here help us gather insight into the 3D structure storms." ] }, { "cell_type": "code", "execution_count": null, "id": "5e8b087a", "metadata": { "tags": [] }, "outputs": [], "source": [ "import xarray as xr\n", "import xradar as xd\n", "import pyvista as pv\n", "import pvxarray # Import to register accessor\n", "from open_radar_data import DATASETS\n", "\n", "pv.set_plot_theme(\"document\")\n", "pv.set_jupyter_backend(\"server\")" ] }, { "cell_type": "code", "execution_count": null, "id": "1dc11e2d-e134-47f4-b0f7-d7ccf9742822", "metadata": {}, "outputs": [], "source": [ "# Temporary manual mode override; waiting for pyvista release including changes from https://github.com/pyvista/pyvista/pull/5798\n", "\n", "pv.global_theme.trame.server_proxy_enabled = False\n", "pv.global_theme.trame.jupyter_extension_enabled = True" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ff462499", "metadata": {}, "source": [ "Fetching CfRadial1 radar data file from open-radar-data repository." ] }, { "cell_type": "code", "execution_count": null, "id": "72e62a95", "metadata": { "tags": [] }, "outputs": [], "source": [ "filename = DATASETS.fetch(\"cfrad.20080604_002217_000_SPOL_v36_SUR.nc\")\n", "radar = xd.io.open_cfradial1_datatree(filename)\n", "radar = radar.xradar.georeference() # Add georeferencing to plot in 3D\n", "list(radar.children)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "42d1af27", "metadata": {}, "source": [ "Now we need to stack all of the sweeps on top of each other to create a 3D data volume" ] }, { "cell_type": "code", "execution_count": null, "id": "7cc4a1f0", "metadata": { "tags": [] }, "outputs": [], "source": [ "ds_list = []\n", "for key in list(radar.children):\n", " if \"sweep\" in key:\n", " ds_list.append(radar[key].ds.drop_duplicates(dim=\"azimuth\"))\n", "ds = xr.concat(ds_list, dim=\"sweep\")\n", "ds" ] }, { "attachments": {}, "cell_type": "markdown", "id": "24717b0f", "metadata": {}, "source": [ "Use `pyvista-xarray`'s accessor to create a PyVista mesh from the data volume. This will build a curvilinear grid (`pyvista.StructuredGrid`)" ] }, { "cell_type": "code", "execution_count": null, "id": "b3a3239b", "metadata": { "tags": [] }, "outputs": [], "source": [ "mesh = ds[\"DBZ\"].pyvista.mesh(x=\"x\", y=\"y\", z=\"z\")\n", "mesh" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ebd3f0c6", "metadata": {}, "source": [ "Preview the data volume" ] }, { "cell_type": "code", "execution_count": null, "id": "21e4da30", "metadata": { "tags": [] }, "outputs": [], "source": [ "mesh.plot(clim=(-20, 60))" ] }, { "attachments": {}, "cell_type": "markdown", "id": "f87e9d75", "metadata": {}, "source": [ "Pseudo-volume rendering with transparent contours" ] }, { "cell_type": "code", "execution_count": null, "id": "c4f3f3b3", "metadata": { "tags": [] }, "outputs": [], "source": [ "pl = pv.Plotter()\n", "pl.add_mesh(mesh.contour(), opacity=0.9, clim=(-20, 60), lighting=False)\n", "pl.show(jupyter_backend=\"static\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "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.9.18" } }, "nbformat": 4, "nbformat_minor": 5 }