{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# NCL_panel_10.py\nThis script illustrates the following concepts:\n   - Drawing Hovmueller plots\n   - Attaching plots along the Y axis\n   - Using a blue-white-red color map\n   - Drawing zonal average plots\n   - Paneling attached plots\n\nSee following URLs to see the reproduced NCL plot & script:\n    - Original NCL script: https://www.ncl.ucar.edu/Applications/Scripts/panel_10.ncl and https://www.ncl.ucar.edu/Applications/Scripts/panel_attach_10.ncl\n    - Original NCL plot: https://www.ncl.ucar.edu/Applications/Images/panel_10_lg.png and https://www.ncl.ucar.edu/Applications/Images/panel_attach_10_lg.png\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Import packages:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nimport xarray as xr\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.axes_grid1.inset_locator import inset_axes\nimport matplotlib.gridspec as gridspec\nfrom cartopy.mpl.gridliner import LongitudeFormatter, LatitudeFormatter\nimport warnings\n\nimport geocat.datafiles as gdf\nimport geocat.viz.util as gvutil\nfrom geocat.viz import cmaps as gvcmaps"
      ]
    },
    {
      "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\n# and load the data into xarrays\nfilename = 'chi200_ud_smooth.nc'\nds = xr.open_dataset(gdf.get('netcdf_files/' + filename))\n\nlon = ds.lon\ntimes = ds.time\nscale = 1000000\nchi = ds.CHI\nchi = chi / scale\n\n# Calculate zonal mean\nwith warnings.catch_warnings():  # This is not needed but is supressing a warning thrown by numpy checking for NaN values\n    warnings.simplefilter(\"ignore\")\n    mean = chi.mean(dim='lon')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Create Single Plot:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, (ax1, ax2) = plt.subplots(nrows=1,\n                               ncols=2,\n                               sharey=True,\n                               figsize=(12, 9),\n                               gridspec_kw=dict(wspace=0,\n                                                width_ratios=[0.75, 0.25],\n                                                left=0.15,\n                                                right=0.85,\n                                                top=0.85,\n                                                bottom=0.15))\n# Create inset axes for color bar\ncax1 = inset_axes(ax1,\n                  width='100%',\n                  height='7%',\n                  loc='lower left',\n                  bbox_to_anchor=(0, -0.15, 1, 1),\n                  bbox_transform=ax1.transAxes,\n                  borderpad=0)\n\n# Draw contour lines\nax1.contour(lon,\n            times,\n            chi,\n            levels=np.arange(-12, 13, 2),\n            colors='black',\n            linestyles='solid',\n            linewidths=.5)\n\n# Draw filled contours\ncf = ax1.contourf(lon,\n                  times,\n                  chi,\n                  levels=np.arange(-12, 13, 2),\n                  cmap=gvcmaps.BlWhRe)\n\n# Draw colorbar with larger tick labels\ncbar = plt.colorbar(cf,\n                    cax=cax1,\n                    orientation='horizontal',\n                    ticks=np.arange(-10, 11, 2))\ncbar.ax.tick_params(labelsize=12)\n\n# Use geocat.viz.util convenience function to set axes limits & tick values\ngvutil.set_axes_limits_and_ticks(ax1,\n                                 xlim=[100, 220],\n                                 ylim=[0, 1.55 * 1e16],\n                                 xticks=[135, 180],\n                                 yticks=np.linspace(0, 1.55 * 1e16, 7),\n                                 xticklabels=['135E', '180'],\n                                 yticklabels=np.arange(0, 181, 30))\n\n# Use geocat.viz.util convenience function to add minor and major tick lines\ngvutil.add_major_minor_ticks(ax1,\n                             x_minor_per_major=3,\n                             y_minor_per_major=3,\n                             labelsize=12)\n\n# Remove tick marks on right side of ax1\nax1.tick_params('y', which='both', right=False)\n\n# Use geocat.viz.util convenience function to add titles\ngvutil.set_titles_and_labels(ax1,\n                             maintitle=\"Pacific Region\",\n                             lefttitle=\"Velocity Potential\",\n                             righttitle=\"m2/s\",\n                             ylabel=\"elapsed time\")\n\n# Format axes for zonal average plot\n# Use geocat.viz.util convenience function to set axes limits & tick values\ngvutil.set_axes_limits_and_ticks(ax2,\n                                 xlim=[-0.6, 0.9],\n                                 ylim=[0, 1.55 * 1e16],\n                                 xticks=np.arange(-0.3, 0.7, 0.3),\n                                 yticks=np.linspace(0, 1.55 * 1e16, 7),\n                                 xticklabels=['-0.30', '', '0.30', ''],\n                                 yticklabels=np.arange(0, 181, 30))\n\n# Use geocat.viz.util convenience function to add minor and major tick lines\ngvutil.add_major_minor_ticks(ax2,\n                             x_minor_per_major=1,\n                             y_minor_per_major=3,\n                             labelsize=12)\n\n# Remove tick marks on left side of ax2\nax2.tick_params('y', which='both', left=False)\n\n# Use geocat.viz.util convenience function to add titles\ngvutil.set_titles_and_labels(ax2,\n                             maintitle=\"Zonal Ave\",\n                             maintitlefontsize=12)\n\n# Plot zonal average\nax2.plot(mean, times, linewidth=0.5, color='black')\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Define helper function to create the four subplots\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def make_subplot(fig, gridspec, xlim):\n    # Create axes for the contour plot and the zonal average plot\n    ax1 = fig.add_subplot(gridspec[0])\n    ax2 = fig.add_subplot(gridspec[1])\n\n    # Draw contour lines\n    ax1.contour(lon,\n                times,\n                chi,\n                levels=np.arange(-12, 13, 2),\n                colors='black',\n                linestyles='solid',\n                linewidths=.5)\n\n    # Draw filled contours, save the mappable to create colorbar later\n    color_mappable = ax1.contourf(lon,\n                                  times,\n                                  chi,\n                                  levels=np.arange(-12, 13, 2),\n                                  cmap=gvcmaps.BlWhRe)\n\n    # Use geocat.viz.util convenience function to add longitude tick labels\n    gvutil.add_lat_lon_ticklabels(ax1)\n\n    # Remove degree symbol from tick labels\n    ax1.xaxis.set_major_formatter(LongitudeFormatter(degree_symbol=''))\n\n    # Use geocat.viz.util convenience function to set axes limits & tick values\n    gvutil.set_axes_limits_and_ticks(ax1,\n                                     xlim=xlim,\n                                     ylim=[0, 1.55 * 1e16],\n                                     xticks=np.arange(xlim[0], xlim[1], 30),\n                                     yticks=np.linspace(0, 1.55 * 1e16, 7),\n                                     yticklabels=[])\n\n    # Use geocat.viz.util convenience function to add minor and major tick lines\n    gvutil.add_major_minor_ticks(ax1,\n                                 x_minor_per_major=2,\n                                 y_minor_per_major=3,\n                                 labelsize=10)\n\n    # Remove tick marks on right side of ax1\n    ax1.tick_params('y', which='both', right=False)\n\n    # Use geocat.viz.util convenience function to add titles\n    gvutil.set_titles_and_labels(ax1,\n                                 lefttitle=\"Velocity Potential\",\n                                 righttitle=\"m2/s\",\n                                 lefttitlefontsize=10,\n                                 righttitlefontsize=10)\n\n    # Format axes for zonal average plot\n    # Use geocat.viz.util convenience function to set axes limits & tick values\n    gvutil.set_axes_limits_and_ticks(ax2,\n                                     xlim=[-0.6, 0.9],\n                                     ylim=[0, 1.55 * 1e16],\n                                     xticks=np.arange(-0.3, 0.7, 0.3),\n                                     yticks=np.linspace(0, 1.55 * 1e16, 7),\n                                     xticklabels=['-0.30', '', '0.30', ''],\n                                     yticklabels=[])\n\n    # Use geocat.viz.util convenience function to add minor and major tick lines\n    gvutil.add_major_minor_ticks(ax2,\n                                 x_minor_per_major=1,\n                                 y_minor_per_major=3,\n                                 labelsize=8)\n\n    # Remove tick marks on left side of ax2\n    ax2.tick_params('y', which='both', left=False)\n\n    # Use geocat.viz.util convenience function to add titles\n    gvutil.set_titles_and_labels(ax2,\n                                 maintitle=\"Zonal Ave\",\n                                 maintitlefontsize=8)\n\n    # Plot zonal average\n    ax2.plot(mean, times, linewidth=0.5, color='black')\n    return color_mappable"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Create the four panel plot\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig = plt.figure(figsize=(10, 10))\n\n# Create a three by two grid to hold the four plots and the colorbar\nouter_grid = gridspec.GridSpec(3, 2,\n                               figure=fig,\n                               hspace=0.35,\n                               height_ratios=[0.475, 0.475, 0.05])\n\n# Create an array to hold the internal gridspecs\ninner_grids = np.empty(4, dtype=gridspec.GridSpec)\n\n# Create the gridspecs for each of the four plots\nfor i in range(0, 4):\n    inner_grids[i] = gridspec.GridSpecFromSubplotSpec(1, 2,\n                                                      subplot_spec=outer_grid[i],\n                                                      wspace=0,\n                                                      width_ratios=[0.75, 0.25])\nmake_subplot(fig, inner_grids[0], [0, 90])\nmake_subplot(fig, inner_grids[1], [90, 180])\nmake_subplot(fig, inner_grids[2], [180, 270])\ncolor_mappable = make_subplot(fig, inner_grids[3], [270, 360])\n\n# Create axes for colorbar and then draw colorbar\ncax = fig.add_subplot(outer_grid[2, :])\nplt.colorbar(color_mappable,\n             cax=cax,\n             ticks=np.arange(-10, 12, 2),\n             orientation='horizontal',\n             drawedges=True)\n\n# Add figure title\nfig.suptitle(filename, fontsize=18, y=0.95)\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
}