{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# NCL_panel_20.py\nThis script illustrates the following concepts:\n   - Drawing four different-sized plots on the same page using gridspec\n\nSee following URLs to see the reproduced NCL plot & script:\n   - Original NCL script: http://www.ncl.ucar.edu/Applications/Scripts/panel_20.ncl\n   - Original NCL plot: http://www.ncl.ucar.edu/Applications/Images/panel_20_lg.png\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Import packages:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import cartopy.crs as ccrs\nfrom cartopy.mpl.gridliner import LongitudeFormatter, LatitudeFormatter\nimport matplotlib.pyplot as plt\nimport matplotlib.gridspec as gridspec\nimport matplotlib.colors as colors\nimport numpy as np\nimport xarray as xr\n\nimport geocat.datafiles as gdf\nfrom geocat.viz import cmaps as gvcmaps\nimport geocat.viz.util as gvutil"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Read in data:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Open a netCDF data file using xarray default engine and load the data into xarrays\nds = xr.open_dataset(gdf.get(\"netcdf_files/uv300.nc\"))\n\n# Extract data from second timestep\ntime_0 = ds.isel(time=0).drop_vars('time')\ntime_1 = ds.isel(time=1).drop_vars('time')\n\n# Ensure longitudes range from 0 to 360 degrees\nU_0 = gvutil.xr_add_cyclic_longitudes(time_0.U, \"lon\")\nU_1 = gvutil.xr_add_cyclic_longitudes(time_1.U, \"lon\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Create helper functions:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def format_linegraph_axes(ax):\n    \"\"\"\n    Format the axes limits, tick marks, and tick labels for the line graphs\n\n    Args:\n        ax (:class: 'matplotlib.Axes'):\n            The set of axes to be manipulated\n    \"\"\"\n    # Use geocat.viz.util convenience function to set axes tick values\n    gvutil.set_axes_limits_and_ticks(ax=ax,\n                                     xlim=(-90, 90),\n                                     ylim=(-20, 50),\n                                     xticks=np.arange(-90, 91, 30),\n                                     yticks=np.arange(-20, 51, 10),\n                                     xticklabels=['90S', '60S', '30S', '0',\n                                                  '30N', '60N', '90N'])\n\n    # Use geocat.viz.util convenience function to add minor and major ticks\n    gvutil.add_major_minor_ticks(ax,\n                                 x_minor_per_major=3,\n                                 y_minor_per_major=5,\n                                 labelsize=12)\n\n\ndef format_contour_axes(ax):\n    \"\"\"\n    Format the axes limits, tick marks, and tick labels for the contour plots\n\n    Args:\n        ax (:class: 'matplotlib.Axes'):\n            The set of axes to be manipulated\n    \"\"\"\n    # Use geocat.viz.util convenience function to set axes tick values\n    gvutil.set_axes_limits_and_ticks(ax=ax,\n                                     xlim=(-180, 180),\n                                     ylim=(-90, 90),\n                                     xticks=np.arange(-180, 181, 30),\n                                     yticks=np.arange(-90, 91, 30))\n\n    # Use geocat.viz.util convenience function to add minor and major ticks\n    gvutil.add_major_minor_ticks(ax, labelsize=8)\n\n    # Use geocat.viz.util convenience function to make plots look like NCL\n    # plots by using latitude, longitude tick labels\n    gvutil.add_lat_lon_ticklabels(ax)\n\n    # Remove the degree symbol from tick labels\n    ax.yaxis.set_major_formatter(LatitudeFormatter(degree_symbol=''))\n    ax.xaxis.set_major_formatter(LongitudeFormatter(degree_symbol=''))\n\n    # Use geocat.viz.util convenience function to set titles and labels\n    gvutil.set_titles_and_labels(ax,\n                                 maintitle='300mb',\n                                 maintitlefontsize=8)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Plot:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig = plt.figure(figsize=(12, 10))\n\n# Create grid with two rows and two columns\n# Use `height_ratios` to adjust the relative heights of the rows\ngrid = gridspec.GridSpec(nrows=2,\n                         ncols=2,\n                         height_ratios=[0.55, 0.45],\n                         hspace=0.1,\n                         figure=fig)\n\n# Choose the map projection\nproj = ccrs.PlateCarree()\n\n# Add the subplots\nax1 = fig.add_subplot(grid[0])  # upper left cell of grid\nax2 = fig.add_subplot(grid[1])  # upper right cell of grid\nax3 = fig.add_subplot(grid[2], projection=proj)  # lower left cell of grid\nax4 = fig.add_subplot(grid[3], projection=proj)  # lower right cell of grid\n\n# Draw coastlines on maps\nax3.coastlines(linewidth=0.5)\nax4.coastlines(linewidth=0.5)\n\n# Use geocat.viz.util convenience function to set titles without calling\n# several matplotlib functions\ngvutil.set_titles_and_labels(ax1,\n                             maintitle='Time=0',\n                             maintitlefontsize=14,\n                             ylabel=U_0.long_name,\n                             labelfontsize=14)\ngvutil.set_titles_and_labels(ax2,\n                             maintitle='Time=1',\n                             maintitlefontsize=14)\n\n# Draw tick labels on the right side of the top right plot\nax2.yaxis.tick_right()\n\n# Use helper function to create linegraphs with identical axes parameters\nformat_linegraph_axes(ax1)\nformat_linegraph_axes(ax2)\n\n# Remove tick labels for top left plot\nax1.set_yticklabels([])\n\n# Use helper function to create contour plots with identical axes parameters\nformat_contour_axes(ax3)\nformat_contour_axes(ax4)\n\n# Add left and right titles for both map plots\nax3.set_title(U_0.long_name, loc='left', y=1.04, fontsize=8)\nax3.set_title('Time = 0', loc='right', y=1.04, fontsize=8)\nax4.set_title(U_0.long_name, loc='left', y=1.04, fontsize=8)\nax4.set_title('Time = 1', loc='right', y=1.04, fontsize=8)\n\n# Plot xy data at a particular longitude\nax1.plot(U_0['lat'],\n         U_0.isel(lon=93).drop_vars('lon').data,\n         c='black',\n         linewidth=0.5)\nax2.plot(U_1['lat'],\n         U_1.isel(lon=93).drop_vars('lon').data,\n         c='black',\n         linewidth=0.5)\n\n# Choose colormap for contour plots\ndivnorm = colors.TwoSlopeNorm(vmin=-15, vcenter=0, vmax=40)\ncmap = gvcmaps.BlueRed\n\n# Specify levels for contours\nlevels = np.arange(-10, 36, 5)\n\n# Add filled contour to maps\ncontour3 = ax3.contourf(U_0['lon'],\n                        U_0['lat'],\n                        U_0.data,\n                        cmap=cmap,\n                        norm=divnorm,\n                        levels=levels,\n                        extend='both')\ncontour4 = ax4.contourf(U_1['lon'],\n                        U_1['lat'],\n                        U_1.data,\n                        cmap=cmap,\n                        norm=divnorm,\n                        levels=levels,\n                        extend='both')\n\n# Add contour line to maps\nax3.contour(U_0['lon'],\n            U_0['lat'],\n            U_0.data,\n            colors='black',\n            linewidths=0.5,\n            linestyles='solid',\n            levels=levels)\nax4.contour(U_1['lon'],\n            U_1['lat'],\n            U_1.data,\n            colors='black',\n            linewidths=0.5,\n            linestyles='solid',\n            levels=levels)\n\n# Create colorbars\ncbar3 = plt.colorbar(contour3,\n                     ax=ax3,\n                     orientation='horizontal',\n                     extendrect=True,\n                     extendfrac='auto',\n                     shrink=0.75,\n                     aspect=13,\n                     drawedges=True,\n                     pad=0.1)\ncbar4 = plt.colorbar(contour4,\n                     ax=ax4,\n                     orientation='horizontal',\n                     extendrect=True,\n                     extendfrac='auto',\n                     shrink=0.75,\n                     aspect=13,\n                     drawedges=True,\n                     pad=0.1)\n\n# Format colorbar ticks and labels\ncbar3.ax.tick_params(labelsize=8)\ncbar4.ax.tick_params(labelsize=8)\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}