{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# NCL_box_3.py\n\nThis script illustrates the following concepts:\n   - Drawing box plots\n   - Adding markers to a box plot\n   - Setting the color of individual boxes in a box plot\n   - Setting the width of individual boxes in a box plot\n\nSee following URLs to see the reproduced NCL plot & script:\n    - Original NCL script: https://www.ncl.ucar.edu/Applications/Scripts/box_3.ncl\n    - Original NCL plot: https://www.ncl.ucar.edu/Applications/Images/box_3_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 matplotlib.pyplot as plt\n\nfrom geocat.viz import util as gvutil"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Generate fake data\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "np.random.seed(200)\ndata = np.random.lognormal(size=(40, 3), mean=1, sigma=.7)\nfor a in range(len(data)):\n    data[a] = [x - 4 for x in data[a]]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Helper function to set edge color of boxes\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def setBoxColor(boxplot, colors):\n\n    # Set edge color of the outside and median lines of the boxes\n    for element in ['boxes', 'medians']:\n        for box, color in zip(boxplot[element], colors):\n            plt.setp(box, color=color)\n\n    # Set the color of the whiskers and caps of the boxes\n    for element in ['whiskers', 'caps']:\n        for box, color in zip(\n                zip(boxplot[element][::2], boxplot[element][1::2]), colors):\n            plt.setp(box, color=color)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Helper function to remove axis \"spines\" on the top and right sides\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def removeSpines(ax):\n\n    ax.spines['right'].set_visible(False)\n    ax.spines['top'].set_visible(False)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Plot:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Create figure and axis\nfig, ax = plt.subplots(figsize=(6, 6))\n\n# Plot each boxplot, set tick labels, and determine box widths\nboxplots = ax.boxplot(data,\n                      labels=['Control', '-2Xna', '2Xna'],\n                      widths=[0.4, 0.4, 0.4],\n                      showfliers=False)\n\n# Set whisker style to dashed\nplt.setp(boxplots['whiskers'], linestyle='--')\n\n# Set boxplot edge colors\nsetBoxColor(boxplots, ['blue', 'red', 'green'])\n\n# Use geocat.viz.util convenience function to set axes tick values\ngvutil.set_axes_limits_and_ticks(ax,\n                                 ylim=(-6.0, 9.0),\n                                 yticks=[-3.0, 0.0, 3.0, 6.0])\n\n# Use geocat.viz.util convenience function to add minor and major tick lines\ngvutil.add_major_minor_ticks(ax,\n                             y_minor_per_major=3,\n                             x_minor_per_major=1,\n                             labelsize=14)\n\n# Use geocat.viz.util convenience function to add title to the plot axis.\ngvutil.set_titles_and_labels(ax, maintitle='Box Plot with Polymarkers')\n\n# Make both major and minor ticks point inwards towards the plot\nax.tick_params(direction=\"in\", which='both')\n\n# Get rid of right and top axis spines\nremoveSpines(ax)\n\n# Set ticks only at left and bottom sides of plot\nax.yaxis.set_ticks_position('left')\nax.xaxis.set_ticks_position('bottom')\n\n# Add another partially transparent axis on top of the first one\nax2 = ax.inset_axes([0, 0, 1, 1])\nax2.patch.set_alpha(0.2)\n\n# Set limits of second axis so markers will line up with boxes on boxplot\nax2.set_xlim(0, 6)\nax2.set_ylim(-6, 9)\n\n# Turn both major and minor ticks in overlayed axis off\nax2.tick_params(which='both',\n                top=False,\n                bottom=False,\n                left=False,\n                right=False,\n                labelleft=False,\n                labelbottom=False)\n\n# Get rid of right and top axis spines\nremoveSpines(ax2)\n\n# Plot red x markers\nax2.scatter(1, 7.7, marker='x', color='red', linewidth=.5, s=100)\nax2.scatter(3, 2.5, marker='x', color='red', linewidth=.5, s=100)\nax2.scatter(5, 2, marker='x', color='red', linewidth=.5, s=100)\n\n# Plot blue o markers\nax2.scatter(1, 2, marker='o', color='darkblue')\nax2.scatter(3, -0.5, marker='o', color='darkblue')\nax2.scatter(5, 1, marker='o', color='darkblue')\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
}