From 13797b3b622a2da8df2d4c91676e818264a2a640 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Sat, 2 Dec 2023 07:45:13 -0700 Subject: [PATCH 1/4] Correct typos and misinfo about chapters --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c5e02208..90a7ae73 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,7 @@ [![nightly-build](https://github.com/UXARRAY/unstructured-grid-viz-cookbook/actions/workflows/nightly-build.yaml/badge.svg)](https://github.com/UXARRAY/unstructured-grid-viz-cookbook/actions/workflows/nightly-build.yaml) [![Binder](https://binder.projectpythia.org/badge_logo.svg)](https://binder.projectpythia.org/v2/gh/ProjectPythia/cookbook-template/main?labpath=notebooks) -This Cookbook is a comprehensive showcase of workflows & techniques for visualuzing Unstructured Grids using UXarray. It orginiated as part of -Project Raijin's NCAR Summer Internships in Parallel Computational Science (SIParCS) project, titled "_Python Data Analysis and Visualization for Unstructured Grids_." +This Cookbook is a comprehensive showcase of workflows & techniques for visualizing Unstructured Grids using [UXarray](https://uxarray.readthedocs.io/). ## Authors @@ -30,7 +29,7 @@ Project Raijin's NCAR Summer Internships in Parallel Computational Science (SIPa ## Structure -This cookbook is split up into six chapters which provide a comprehensive overview of how to use UXarray to work with and visualuze unstructured grid datasets. +This cookbook is split up into three chapters that provide a comprehensive overview of how to use UXarray to work with and visualuze unstructured grid datasets. #### **1. Introduction to UXarray & Unstructured Grids** @@ -38,8 +37,6 @@ This cookbook is split up into six chapters which provide a comprehensive overvi #### **3. UXarray Visualization** -#### **4. Performance & Data Fidelity Considerations** - ## Running the Notebooks You can either run the notebook using [Binder](https://binder.projectpythia.org/) or on your local machine. From a15f58b4cf3f18e1f3e469333f1e8bd74b3d74f6 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Sat, 2 Dec 2023 10:38:37 -0700 Subject: [PATCH 2/4] Switch to using 480km data instead of 120km for global visibility of mesh --- .../03-uxarray-vis/02-grid-topology.ipynb | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/notebooks/03-uxarray-vis/02-grid-topology.ipynb b/notebooks/03-uxarray-vis/02-grid-topology.ipynb index 268e390a..3085fcd9 100644 --- a/notebooks/03-uxarray-vis/02-grid-topology.ipynb +++ b/notebooks/03-uxarray-vis/02-grid-topology.ipynb @@ -89,8 +89,11 @@ "source": [ "# File paths\n", "file_dir = \"../../meshfiles/\"\n", - "grid_filename = \"oQU120.grid.nc\"\n", - "data_filename = \"oQU120.data.nc\"\n", + "\n", + "# We use 480km dataset in this example but there is also 120km dataset\n", + "# in the file directory that can be further explored\n", + "grid_filename = \"oQU480.grid.nc\"\n", + "data_filename = \"oQU480.data.nc\"\n", "\n", "# A standalone grid can be opened for immediate visualization\n", "ux_grid = ux.open_grid(file_dir + grid_filename)\n", @@ -143,8 +146,6 @@ "source": [ "ux_grid.plot(\n", " title=\"Default Grid Plot Method\",\n", - " xlim=(-170, -50),\n", - " ylim=(10, 80),\n", " width=700,\n", " height=350,\n", ")" @@ -159,6 +160,15 @@ ":::" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ":::{tip}\n", + "Try `xlim` and `ylim` args with the above plot to plot a region of interest only, e.g. `xlim=(-170, -50), ylim=(10, 80)`\n", + ":::" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -184,8 +194,6 @@ "ux_grid.plot.mesh(\n", " exclude_antimeridian=True,\n", " title=\"Mesh - Exclude Antimeridian Polygons\",\n", - " xlim=(-170, -50),\n", - " ylim=(10, 80),\n", " width=700,\n", " height=350,\n", ")" @@ -212,7 +220,7 @@ "outputs": [], "source": [ "ux_grid.plot.edges(\n", - " backend=\"matplotlib\", title=\"Edges - Matplotlib Backend\", fig_size=200\n", + " backend=\"matplotlib\", title=\"Edges - Matplotlib Backend\", fig_size=300, aspect=2\n", ")" ] }, @@ -236,9 +244,7 @@ "metadata": {}, "outputs": [], "source": [ - "ux_grid.plot.nodes(\n", - " size=1, title=\"Nodes\", xlim=(-170, -50), ylim=(10, 80), width=700, height=350\n", - ")" + "ux_grid.plot.nodes(size=1, title=\"Nodes\", width=700, height=350)" ] }, { @@ -270,9 +276,7 @@ "metadata": {}, "outputs": [], "source": [ - "ux_grid.plot.face_centers(\n", - " size=1, title=\"Face Centers\", xlim=(-170, -50), ylim=(10, 80), width=700, height=350\n", - ")" + "ux_grid.plot.face_centers(size=1, title=\"Face Centers\", width=700, height=350)" ] }, { @@ -290,9 +294,7 @@ "metadata": {}, "outputs": [], "source": [ - "ux_grid.plot.edge_centers(\n", - " size=1, title=\"Edge Centers\", xlim=(-170, -50), ylim=(10, 80), width=700, height=350\n", - ")" + "ux_grid.plot.edge_centers(size=1, title=\"Edge Centers\", width=700, height=350)" ] }, { @@ -331,8 +333,8 @@ " * uxds.uxgrid.plot.edge_centers(color=\"Green\", size=1)\n", ").opts(\n", " title=\"Node, Edge, & Face Coordinates\",\n", - " xlim=(-110, -80),\n", - " ylim=(10, 30),\n", + " xlim=(-170, -50),\n", + " ylim=(10, 80),\n", " width=700,\n", " height=350,\n", ")" From f826fdee7f807f9204e7c66840832d0b69277107 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Sat, 2 Dec 2023 10:51:19 -0700 Subject: [PATCH 3/4] Adjust titles and add an admonition into first notebook --- .../01-unstructured-grid-overview.ipynb | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/notebooks/01-intro/01-unstructured-grid-overview.ipynb b/notebooks/01-intro/01-unstructured-grid-overview.ipynb index 898de8ad..e5f435e3 100644 --- a/notebooks/01-intro/01-unstructured-grid-overview.ipynb +++ b/notebooks/01-intro/01-unstructured-grid-overview.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Unstructured Grid Overview" + "# Unstructured Grids Overview" ] }, { @@ -48,7 +48,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Structured Grid\n", + "## Structured Grids\n", "A few advantages of structured grids are:\n", "- Uniform Representation: Simplifies numerical methods and enhances result interpretation.\n", " \n", @@ -134,7 +134,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Unstructured Grids" + "## Unstructured Grids" ] }, { @@ -239,7 +239,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Why UXarray for unstructured grids?\n", + "## Why UXarray for Unstructured Grids?\n", "\n", "- It inherits from Xarray, providing simplified data using familiar (Xarray like) data structures and operations.\n", " \n", @@ -260,8 +260,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ + ":::{info}\n", "This notebook serves as an introduction to unstructured grids and UXarray. For more information, please visit the UXarray documentation at https://uxarray.readthedocs.io/en/latest/ and specifically see the example section: https://uxarray.readthedocs.io/en/latest/examples.html\n", - "\n", + ":::" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What is next?\n", "The next sections will start with basic building blocks of UXarray and then slowly dive into more advanced features." ] } @@ -282,7 +290,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.11.6" }, "nbdime-conflicts": { "local_diff": [ From 18c7ab3176e924d1ac10991d1de5ce6bb75fa503 Mon Sep 17 00:00:00 2001 From: erogluorhan Date: Sat, 2 Dec 2023 11:19:07 -0700 Subject: [PATCH 4/4] Revise README, notebooks/01-intro/01 and notebooks/01-intro/02 --- README.md | 8 +- .../01-unstructured-grid-overview.ipynb | 34 ++- notebooks/01-intro/02-data-structures.ipynb | 198 +++++++++++------- 3 files changed, 148 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index 90a7ae73..e43b2abd 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,13 @@ This Cookbook is a comprehensive showcase of workflows & techniques for visualiz ## Structure -This cookbook is split up into three chapters that provide a comprehensive overview of how to use UXarray to work with and visualuze unstructured grid datasets. +This cookbook is split up into three chapters that provide a detailed overview of how to use UXarray to work with and visualuze unstructured grid datasets: -#### **1. Introduction to UXarray & Unstructured Grids** +**1. Introduction to UXarray & Unstructured Grids** -#### **2. Methods & Libraries for Unstructured Grid Visualization** +**2. Methods & Libraries for Unstructured Grid Visualization** -#### **3. UXarray Visualization** +**3. UXarray Visualization** ## Running the Notebooks diff --git a/notebooks/01-intro/01-unstructured-grid-overview.ipynb b/notebooks/01-intro/01-unstructured-grid-overview.ipynb index e5f435e3..09cf875a 100644 --- a/notebooks/01-intro/01-unstructured-grid-overview.ipynb +++ b/notebooks/01-intro/01-unstructured-grid-overview.ipynb @@ -18,7 +18,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The goal of this notebook is to provide a brief overview of unstructured grids and provide a teaser of plotting with the UXarray package.\n", + "The goal of this notebook is to provide a brief overview of unstructured grids and provide a teaser of plotting with the [UXarray](https://uxarray.readthedocs.io/) package.\n", + "\n", "Contents:\n", "1. Structured vs. Unstructured Grids\n", "2. Structured Grids\n", @@ -137,6 +138,13 @@ "## Unstructured Grids" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Characteristic features of unstructured grids are:" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -232,7 +240,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "NOTE: This is a very basic example of an unstructured grid with triangles. There are very specialized libraries to create unstructured grids. Often the region of interest is meshed with a finer resolution. The mesh is then coarsened in areas where the resolution is not needed. This is done to reduce the number of elements and improve computational efficiency." + ":::{note}\n", + "This is a very basic example of an unstructured grid with triangles. There are very specialized libraries to create unstructured grids. Often the region of interest is meshed with a finer resolution. The mesh is then coarsened in areas where the resolution is not needed. This is done to reduce the number of elements and improve computational efficiency.\n", + ":::" ] }, { @@ -241,26 +251,28 @@ "source": [ "## Why UXarray for Unstructured Grids?\n", "\n", - "- It inherits from Xarray, providing simplified data using familiar (Xarray like) data structures and operations.\n", - " \n", - "- Bring standardization to unstructured mesh support for climate data analysis and visualization.\n", + "UXarray, which stands for \"Unstructured-Xarray\", is a Python package that provides Xarray-styled functionality for working with unstructured grids built around the UGRID conventions. UXarray can simplify working with unstructured grids because it:\n", "\n", - "- Adherence to the UGRID specification for compatibility across a variety of mesh formats.\n", + "- Enables significant data analysis and visualization functionality to be executed dircetly on unstructured grids\n", + "\n", + "- Inherits from Xarray, providing simplified data using familiar (Xarray-like) data structures and operations\n", + " \n", + "- Brings standardization to unstructured mesh support for climate data analysis and visualization\n", "\n", - "- Optimized data structures and algorithms for handling large and complex unstructured datasets. \n", + "- Adheres to the UGRID specification for compatibility across a variety of mesh formats\n", "\n", - "- Enhanced Interoperability and Community Collaboration.\n", + "- Builds on optimized data structures and algorithms for handling large and complex unstructured datasets\n", "\n", - "- One interface for a variety of unstructured grid formats.\n", + "- Supports enhanced interoperability and community collaboration\n", "\n", - "There are unstructured grid format such as Exodus, SCRIP, MPAS, UGRID etc. UXarray is a library that can read and write many such unstructured grid formats. The specific focus of UXarray is to provide a common interface to access and operate on unstructured grids in the climate science community." + "- Provides a single interface for supporting a variety of unstructured grid formats including UGRID, MPAS, SCRIP, and Exodus" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - ":::{info}\n", + ":::{note}\n", "This notebook serves as an introduction to unstructured grids and UXarray. For more information, please visit the UXarray documentation at https://uxarray.readthedocs.io/en/latest/ and specifically see the example section: https://uxarray.readthedocs.io/en/latest/examples.html\n", ":::" ] diff --git a/notebooks/01-intro/02-data-structures.ipynb b/notebooks/01-intro/02-data-structures.ipynb index 47d38d69..16fe91be 100644 --- a/notebooks/01-intro/02-data-structures.ipynb +++ b/notebooks/01-intro/02-data-structures.ipynb @@ -10,113 +10,139 @@ }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ - "UXarray, which stands for \"Unstructured-Xarray\", extends upon Xarray's core data structures and provides functionality for operating on unstructured (a.k.a. non-regular) grids. \n", + "UXarray extends upon Xarray's core data structures (i.e. Dataset and DataArray) and provides functionality for operating on unstructured (a.k.a. non-regular) grids. \n", "\n", "This notebook will showcase the core UXarray data structures and how to interact with them" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "import uxarray as ux" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", - "source": [], "metadata": { - "collapsed": false - } - }, - { - "cell_type": "markdown", + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "First, lets specify the paths to our Grid and Data files. As mentioned in the previous notebook, unstructured grids are typically separated into two files: one containing the grid topology and one containing data variables that reside on that grid." - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "file_dir = \"../../meshfiles/\"\n", "grid_filename = file_dir + \"oQU480.grid.nc\"\n", "data_filename = file_dir + \"oQU480.data.nc\"" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "## `Grid` Data Structure\n", "\n", - "A grid file can be opened standalone using the `ux.open_grid` method, which is a catch-all method that parses the provided input and returns a `Grid` object with grid coordinate and connectivity variables represented in the UGRID conventions.\n", + "An unstructured grid file can be opened standalone using the `ux.open_grid` method, which is a catch-all method that parses the provided input and returns a `Grid` object with grid coordinate and connectivity variables represented in the UGRID conventions.\n", "\n", "Printing our `Grid` instance shows all available grid variables and original grid type.\n" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "grid = ux.open_grid(grid_filename)\n", "grid" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "We can access our coordinate, connectivity, and other descriptor variables as attributes through this `Grid` instance" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "grid.node_lon" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "grid.face_node_connectivity" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "## `UxDataset` & `UxDataArray` Data Structures\n", "\n", @@ -125,84 +151,102 @@ "The major difference between them is that UXarray's implementation is paired with a `Grid` object, accessed through the `.uxgrid` property.\n", "\n", "UXarray also provides a overloaded `ux.open_dataset` method, which takes in both a Grid and Data file path to construct a `UxDataset`\n" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "uxds = ux.open_dataset(grid_filename, data_filename)\n", "uxds" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "We can see that our `UxDataset` has a single data variable \"bottomDepth\", which is mapped to each face (as specified by the \"n_face\" dimension).\n", "\n", "We can access this variable by indexing our `UxDataset` to obtain a `UxDataArray`" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "uxds[\"bottomDepth\"]" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "You can access the `Grid` instance using the `.uxgrid` attribute, which is linked to every `UxDataset` and `UxDataArray`" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "uxds.uxgrid" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "source": [ "Each `UxDataArray` under a `UxDataset` is linked to the same `Grid` object" - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", "execution_count": null, + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, "outputs": [], "source": [ "uxds.uxgrid == uxds[\"bottomDepth\"].uxgrid" - ], - "metadata": { - "collapsed": false - } + ] } ], "metadata": { @@ -221,7 +265,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.11" + "version": "3.11.6" }, "nbdime-conflicts": { "local_diff": [