|
1 | 1 | { |
2 | 2 | "cells": [ |
3 | 3 | { |
| 4 | + "attachments": {}, |
4 | 5 | "cell_type": "markdown", |
5 | 6 | "id": "a31785d6-310c-4871-9ac6-064a7874945f", |
6 | 7 | "metadata": { |
7 | 8 | "tags": [] |
8 | 9 | }, |
9 | 10 | "source": [ |
10 | 11 | "# Horizontal Regridding\n", |
| 12 | + "\n", |
11 | 13 | "Author: [Jason Boutte](https://github.com/jasonb5)\n", |
12 | 14 | "\n", |
13 | 15 | "Date: 08/24/22\n", |
14 | 16 | "\n", |
15 | 17 | "Related APIs:\n", |
16 | 18 | "\n", |
17 | | - "* [xarray.Dataset.regridder.horizontal](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
| 19 | + "- [xarray.Dataset.regridder.horizontal](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
18 | 20 | "\n", |
19 | 21 | "The data used in this example can be found through the [Earth System Grid Federation (ESGF) search portal](https://aims2.llnl.gov/search).\n", |
20 | 22 | "\n", |
21 | 23 | "## Overview\n", |
| 24 | + "\n", |
22 | 25 | "We'll cover horizontal regridding using the `xESMF` and `Regrid2` tools as well as various methods supported by `xESMF`.\n", |
23 | 26 | "\n", |
24 | | - "It should be noted that `Regrid2` treats the grid cells as being flat." |
| 27 | + "It should be noted that `Regrid2` treats the grid cells as being flat.\n" |
25 | 28 | ] |
26 | 29 | }, |
27 | 30 | { |
|
39 | 42 | ] |
40 | 43 | }, |
41 | 44 | { |
| 45 | + "attachments": {}, |
42 | 46 | "cell_type": "markdown", |
43 | 47 | "id": "7d904843-4079-4ebe-a3d0-ab439e8ce052", |
44 | 48 | "metadata": {}, |
45 | 49 | "source": [ |
46 | 50 | "## 1. Open the Dataset\n", |
| 51 | + "\n", |
47 | 52 | "We are using xarray's OPeNDAP support to read a netCDF4 dataset file directly from its source. The data is not loaded over the network until we perform operations on it (e.g., temperature unit adjustment).\n", |
48 | 53 | "\n", |
49 | | - "More information on the xarray's OPeNDAP support can be found [here](https://docs.xarray.dev/en/stable/user-guide/io.html#opendap)." |
| 54 | + "More information on the xarray's OPeNDAP support can be found [here](https://docs.xarray.dev/en/stable/user-guide/io.html#opendap).\n" |
50 | 55 | ] |
51 | 56 | }, |
52 | 57 | { |
|
640 | 645 | } |
641 | 646 | ], |
642 | 647 | "source": [ |
643 | | - "filepath = 'http://aims3.llnl.gov/thredds/dodsC/css03_data/CMIP6/CMIP/CCCma/CanESM5/historical/r13i1p1f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r13i1p1f1_gn_185001-201412.nc'\n", |
| 648 | + "filepath = \"http://aims3.llnl.gov/thredds/dodsC/css03_data/CMIP6/CMIP/CCCma/CanESM5/historical/r13i1p1f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r13i1p1f1_gn_185001-201412.nc\"\n", |
644 | 649 | "\n", |
645 | 650 | "ds = xcdat.open_dataset(filepath)\n", |
646 | 651 | "\n", |
647 | 652 | "# Unit adjust (-273.15, K to C)\n", |
648 | | - "ds['tas'] = ds['tas'] - 273.15\n", |
| 653 | + "ds[\"tas\"] = ds[\"tas\"] - 273.15\n", |
649 | 654 | "\n", |
650 | | - "ds" |
| 655 | + "ds\n" |
651 | 656 | ] |
652 | 657 | }, |
653 | 658 | { |
| 659 | + "attachments": {}, |
654 | 660 | "cell_type": "markdown", |
655 | 661 | "id": "1aa0dc89-d664-4721-8759-45065060a5b1", |
656 | 662 | "metadata": {}, |
657 | 663 | "source": [ |
658 | 664 | "## 2. Create the output grid\n", |
| 665 | + "\n", |
659 | 666 | "Related API: [xcdat.create_gaussian_grid()](../generated/xcdat.create_gaussian_grid.rst)\n", |
660 | 667 | "\n", |
661 | | - "In this example, we will generate a gaussian grid with 32 latitudes to regrid our input data to." |
| 668 | + "In this example, we will generate a gaussian grid with 32 latitudes to regrid our input data to.\n" |
662 | 669 | ] |
663 | 670 | }, |
664 | 671 | { |
|
685 | 692 | "\n", |
686 | 693 | "fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n", |
687 | 694 | "\n", |
688 | | - "ds.regridder.grid.plot.scatter('lon', 'lat', s=0.01, ax=axes[0])\n", |
689 | | - "axes[0].set_title('Input Grid')\n", |
| 695 | + "ds.regridder.grid.plot.scatter(\"lon\", \"lat\", s=0.01, ax=axes[0])\n", |
| 696 | + "axes[0].set_title(\"Input Grid\")\n", |
690 | 697 | "\n", |
691 | | - "output_grid.plot.scatter('lon', 'lat', s=0.1, ax=axes[1])\n", |
692 | | - "axes[1].set_title('Output Grid')\n", |
| 698 | + "output_grid.plot.scatter(\"lon\", \"lat\", s=0.1, ax=axes[1])\n", |
| 699 | + "axes[1].set_title(\"Output Grid\")\n", |
693 | 700 | "\n", |
694 | | - "plt.tight_layout()" |
| 701 | + "plt.tight_layout()\n" |
695 | 702 | ] |
696 | 703 | }, |
697 | 704 | { |
| 705 | + "attachments": {}, |
698 | 706 | "cell_type": "markdown", |
699 | 707 | "id": "9d5fe21a-85ef-4737-95fd-0a0868e89579", |
700 | 708 | "metadata": {}, |
701 | 709 | "source": [ |
702 | 710 | "## 3. Regrid the data\n", |
| 711 | + "\n", |
703 | 712 | "Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
704 | 713 | "\n", |
705 | | - "Here we will regrid the input data to the ouptut grid using the `xESMF` tool and the `bilinear` method." |
| 714 | + "Here we will regrid the input data to the ouptut grid using the `xESMF` tool and the `bilinear` method.\n" |
706 | 715 | ] |
707 | 716 | }, |
708 | 717 | { |
|
725 | 734 | } |
726 | 735 | ], |
727 | 736 | "source": [ |
728 | | - "output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method='bilinear')\n", |
| 737 | + "output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"xesmf\", method=\"bilinear\")\n", |
729 | 738 | "\n", |
730 | 739 | "fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n", |
731 | 740 | "\n", |
732 | 741 | "ds.tas.isel(time=0).plot(ax=axes[0])\n", |
733 | | - "axes[0].set_title('Input data')\n", |
| 742 | + "axes[0].set_title(\"Input data\")\n", |
734 | 743 | "\n", |
735 | 744 | "output.tas.isel(time=0).plot(ax=axes[1])\n", |
736 | | - "axes[1].set_title('Output data')\n", |
| 745 | + "axes[1].set_title(\"Output data\")\n", |
737 | 746 | "\n", |
738 | | - "plt.tight_layout()" |
| 747 | + "plt.tight_layout()\n" |
739 | 748 | ] |
740 | 749 | }, |
741 | 750 | { |
| 751 | + "attachments": {}, |
742 | 752 | "cell_type": "markdown", |
743 | 753 | "id": "4084129e-dd96-4d0d-ae01-4a66f897e4e5", |
744 | 754 | "metadata": {}, |
745 | 755 | "source": [ |
746 | 756 | "## 4. Regridding algorithms\n", |
| 757 | + "\n", |
747 | 758 | "Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
748 | 759 | "\n", |
749 | 760 | "In this example, we will compare the different regridding methods supported by `xESMF`.\n", |
|
752 | 763 | "\n", |
753 | 764 | "Methods:\n", |
754 | 765 | "\n", |
755 | | - "* bilinear\n", |
756 | | - "* conservative\n", |
757 | | - "* nearest_s2d\n", |
758 | | - "* nearest_d2s\n", |
759 | | - "* patch" |
| 766 | + "- bilinear\n", |
| 767 | + "- conservative\n", |
| 768 | + "- nearest_s2d\n", |
| 769 | + "- nearest_d2s\n", |
| 770 | + "- patch\n" |
760 | 771 | ] |
761 | 772 | }, |
762 | 773 | { |
|
779 | 790 | } |
780 | 791 | ], |
781 | 792 | "source": [ |
782 | | - "methods = ['bilinear', 'conservative', 'nearest_s2d', 'nearest_d2s', 'patch']\n", |
| 793 | + "methods = [\"bilinear\", \"conservative\", \"nearest_s2d\", \"nearest_d2s\", \"patch\"]\n", |
783 | 794 | "\n", |
784 | 795 | "fig, axes = plt.subplots(3, 2, figsize=(16, 12))\n", |
785 | 796 | "\n", |
786 | 797 | "axes = axes.flatten()\n", |
787 | 798 | "\n", |
788 | 799 | "for i, method in enumerate(methods):\n", |
789 | | - " output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method=method)\n", |
| 800 | + " output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"xesmf\", method=method)\n", |
790 | 801 | "\n", |
791 | 802 | " output.tas.isel(time=0).plot(ax=axes[i])\n", |
792 | 803 | "\n", |
793 | 804 | " axes[i].set_title(method)\n", |
794 | 805 | "\n", |
795 | 806 | "axes[-1].set_visible(False)\n", |
796 | 807 | "\n", |
797 | | - "plt.tight_layout()" |
| 808 | + "plt.tight_layout()\n" |
798 | 809 | ] |
799 | 810 | }, |
800 | 811 | { |
| 812 | + "attachments": {}, |
801 | 813 | "cell_type": "markdown", |
802 | 814 | "id": "92685e37-ed43-42c2-b9b3-8b4722075ebc", |
803 | 815 | "metadata": {}, |
804 | 816 | "source": [ |
805 | 817 | "## 5. Masking\n", |
| 818 | + "\n", |
806 | 819 | "Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
807 | 820 | "\n", |
808 | 821 | "`xESMF` supports masking by simply adding a data variable with the id `mask`.\n", |
809 | 822 | "\n", |
810 | | - "See `xESMF` [documentation](https://pangeo-xesmf.readthedocs.io/en/latest/notebooks/Masking.html) for additonal details." |
| 823 | + "See `xESMF` [documentation](https://pangeo-xesmf.readthedocs.io/en/latest/notebooks/Masking.html) for additonal details.\n" |
811 | 824 | ] |
812 | 825 | }, |
813 | 826 | { |
|
830 | 843 | } |
831 | 844 | ], |
832 | 845 | "source": [ |
833 | | - "ds['mask'] = xr.where(ds.tas.isel(time=0)<-10, 1, 0)\n", |
| 846 | + "ds[\"mask\"] = xr.where(ds.tas.isel(time=0) < -10, 1, 0)\n", |
834 | 847 | "\n", |
835 | | - "masked_output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method='bilinear')\n", |
| 848 | + "masked_output = ds.regridder.horizontal(\n", |
| 849 | + " \"tas\", output_grid, tool=\"xesmf\", method=\"bilinear\"\n", |
| 850 | + ")\n", |
836 | 851 | "\n", |
837 | 852 | "fig, axes = plt.subplots(ncols=2, figsize=(18, 4))\n", |
838 | 853 | "\n", |
839 | | - "ds['mask'].plot(ax=axes[0], cmap='binary_r')\n", |
840 | | - "axes[0].set_title('Mask')\n", |
| 854 | + "ds[\"mask\"].plot(ax=axes[0], cmap=\"binary_r\")\n", |
| 855 | + "axes[0].set_title(\"Mask\")\n", |
841 | 856 | "\n", |
842 | 857 | "masked_output.tas.isel(time=0).plot(ax=axes[1])\n", |
843 | | - "axes[1].set_title('Masked output')\n", |
| 858 | + "axes[1].set_title(\"Masked output\")\n", |
844 | 859 | "\n", |
845 | | - "plt.tight_layout()" |
| 860 | + "plt.tight_layout()\n" |
846 | 861 | ] |
847 | 862 | }, |
848 | 863 | { |
| 864 | + "attachments": {}, |
849 | 865 | "cell_type": "markdown", |
850 | 866 | "id": "99daebe0-0b0d-4a88-988a-5e2d685de80d", |
851 | 867 | "metadata": {}, |
852 | 868 | "source": [ |
853 | 869 | "## 6. Regridding using `regrid2`\n", |
| 870 | + "\n", |
854 | 871 | "Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n", |
855 | 872 | "\n", |
856 | 873 | "`Regrid2` is a conservative regridder for rectilinear (lat/lon) grids originally from the `cdutil` package from `CDAT`.\n", |
857 | 874 | "\n", |
858 | | - "This regridder assumes constant latitude lines when generating weights." |
| 875 | + "This regridder assumes constant latitude lines when generating weights.\n" |
859 | 876 | ] |
860 | 877 | }, |
861 | 878 | { |
|
888 | 905 | } |
889 | 906 | ], |
890 | 907 | "source": [ |
891 | | - "output = ds.regridder.horizontal('tas', output_grid, tool='regrid2')\n", |
| 908 | + "output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"regrid2\")\n", |
892 | 909 | "\n", |
893 | 910 | "fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n", |
894 | 911 | "\n", |
895 | 912 | "ds.tas.isel(time=0).plot(ax=axes[0])\n", |
896 | 913 | "\n", |
897 | | - "output.tas.isel(time=0).plot(ax=axes[1])" |
| 914 | + "output.tas.isel(time=0).plot(ax=axes[1])\n" |
898 | 915 | ] |
899 | 916 | } |
900 | 917 | ], |
901 | 918 | "metadata": { |
902 | 919 | "kernelspec": { |
903 | | - "display_name": "Python 3.9.13 ('xcdat_dev')", |
| 920 | + "display_name": "Python 3 (ipykernel)", |
904 | 921 | "language": "python", |
905 | 922 | "name": "python3" |
906 | 923 | }, |
|
914 | 931 | "name": "python", |
915 | 932 | "nbconvert_exporter": "python", |
916 | 933 | "pygments_lexer": "ipython3", |
917 | | - "version": "3.9.13" |
| 934 | + "version": "3.10.8" |
918 | 935 | }, |
919 | 936 | "vscode": { |
920 | 937 | "interpreter": { |
|
0 commit comments