OSGeoLive-Notebooks/Pandas/solved - 05 - Time series d...

9014 lines
636 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p><font size=\"6\"><b>Pandas: Working with time series data</b></font></p>\n",
"\n",
"> *© 2016, Joris Van den Bossche and Stijn Van Hoey (<mailto:jorisvandenbossche@gmail.com>, <mailto:stijnvanhoey@gmail.com>). Licensed under [CC BY 4.0 Creative Commons](http://creativecommons.org/licenses/by/4.0/)*\n",
"\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"pd.options.display.max_rows = 8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction: `datetime` module"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Standard Python contains the `datetime` module to handle with date and time data:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"import datetime"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"datetime.datetime(2016, 12, 19, 13, 30)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dt = datetime.datetime(year=2016, month=12, day=19, hour=13, minute=30)\n",
"dt"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2016-12-19 13:30:00\n"
]
}
],
"source": [
"print(dt) # .day,..."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"19 December 2016\n"
]
}
],
"source": [
"print(dt.strftime(\"%d %B %Y\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Dates and times in pandas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The ``Timestamp`` object"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pandas has its own date and time objects, which are compatible with the standard `datetime` objects, but provide some more functionality to work with. \n",
"\n",
"The `Timestamp` object can also be constructed from a string:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-12-19 00:00:00')"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts = pd.Timestamp('2016-12-19')\n",
"ts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Like with `datetime.datetime` objects, there are several useful attributes available on the `Timestamp`. For example, we can get the month:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"12"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts.month"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-12-24 00:00:00')"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts + pd.Timedelta('5 days')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Parsing datetime strings "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![](http://imgs.xkcd.com/comics/iso_8601.png)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Unfortunately, when working with real world data, you encounter many different `datetime` formats. Most of the time when you have to deal with them, they come in text format, e.g. from a `CSV` file. To work with those data in Pandas, we first have to *parse* the strings to actual `Timestamp` objects."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
"<b>REMEMBER</b>: <br><br>\n",
"\n",
"from string formatted dates to Timestamp objects: `to_datetime` function\n",
"</div>\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-12-09 00:00:00')"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.to_datetime(\"2016-12-09\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-09-12 00:00:00')"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.to_datetime(\"09/12/2016\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-12-09 00:00:00')"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.to_datetime(\"09/12/2016\", dayfirst=True)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"Timestamp('2016-12-09 00:00:00')"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.to_datetime(\"09/12/2016\", format=\"%d/%m/%Y\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"A detailed overview of how to specify the `format` string, see the table in the python documentation: https://docs.python.org/3.5/library/datetime.html#strftime-and-strptime-behavior"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## `Timestamp` data in a Series or DataFrame column"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"s = pd.Series(['2016-12-09 10:00:00', '2016-12-09, 11:00:00', '2016-12-09 12:00:00'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `to_datetime` function can also be used to convert a full series of strings:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"ts = pd.to_datetime(s)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"0 2016-12-09 10:00:00\n",
"1 2016-12-09 11:00:00\n",
"2 2016-12-09 12:00:00\n",
"dtype: datetime64[ns]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice the data type of this series: the `datetime64[ns]` dtype. This indicates that we have a series of actual datetime values."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The same attributes as on single `Timestamp`s are also available on a Series with datetime data, using the **`.dt`** accessor:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"0 10\n",
"1 11\n",
"2 12\n",
"dtype: int64"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts.dt.hour"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"0 4\n",
"1 4\n",
"2 4\n",
"dtype: int64"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts.dt.weekday"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To quickly construct some regular time series data, the [``pd.date_range``](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.date_range.html) function comes in handy:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"0 2016-01-01 00:00:00\n",
"1 2016-01-01 03:00:00\n",
"2 2016-01-01 06:00:00\n",
"3 2016-01-01 09:00:00\n",
" ... \n",
"6 2016-01-01 18:00:00\n",
"7 2016-01-01 21:00:00\n",
"8 2016-01-02 00:00:00\n",
"9 2016-01-02 03:00:00\n",
"dtype: datetime64[ns]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.Series(pd.date_range(start=\"2016-01-01\", periods=10, freq='3H'))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Time series data: `Timestamp` in the index"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## River discharge example data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For the following demonstration of the time series functionality, we use a sample of discharge data of the Maarkebeek (Flanders) with 3 hour averaged values, derived from the [Waterinfo website](https://www.waterinfo.be/)."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"data = pd.read_csv(\"data/flowdata.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Time</th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2009-01-01 00:00:00</td>\n",
" <td>0.137417</td>\n",
" <td>0.097500</td>\n",
" <td>0.016833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2009-01-01 03:00:00</td>\n",
" <td>0.131250</td>\n",
" <td>0.088833</td>\n",
" <td>0.016417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2009-01-01 06:00:00</td>\n",
" <td>0.113500</td>\n",
" <td>0.091250</td>\n",
" <td>0.016750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>2009-01-01 09:00:00</td>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2009-01-01 12:00:00</td>\n",
" <td>0.140917</td>\n",
" <td>0.096167</td>\n",
" <td>0.017000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Time L06_347 LS06_347 LS06_348\n",
"0 2009-01-01 00:00:00 0.137417 0.097500 0.016833\n",
"1 2009-01-01 03:00:00 0.131250 0.088833 0.016417\n",
"2 2009-01-01 06:00:00 0.113500 0.091250 0.016750\n",
"3 2009-01-01 09:00:00 0.135750 0.091500 0.016250\n",
"4 2009-01-01 12:00:00 0.140917 0.096167 0.017000"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We already know how to parse a date column with Pandas:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"data['Time'] = pd.to_datetime(data['Time'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With `set_index('datetime')`, we set the column with datetime values as the index, which can be done by both `Series` and `DataFrame`."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"data = data.set_index(\"Time\")"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01 00:00:00</th>\n",
" <td>0.137417</td>\n",
" <td>0.097500</td>\n",
" <td>0.016833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 03:00:00</th>\n",
" <td>0.131250</td>\n",
" <td>0.088833</td>\n",
" <td>0.016417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 06:00:00</th>\n",
" <td>0.113500</td>\n",
" <td>0.091250</td>\n",
" <td>0.016750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 09:00:00</th>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 21:00:00</th>\n",
" <td>0.898250</td>\n",
" <td>0.898250</td>\n",
" <td>0.077167</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-02 00:00:00</th>\n",
" <td>0.860000</td>\n",
" <td>0.860000</td>\n",
" <td>0.075000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>11697 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 00:00:00 0.137417 0.097500 0.016833\n",
"2009-01-01 03:00:00 0.131250 0.088833 0.016417\n",
"2009-01-01 06:00:00 0.113500 0.091250 0.016750\n",
"2009-01-01 09:00:00 0.135750 0.091500 0.016250\n",
"... ... ... ...\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"2013-01-01 21:00:00 0.898250 0.898250 0.077167\n",
"2013-01-02 00:00:00 0.860000 0.860000 0.075000\n",
"\n",
"[11697 rows x 3 columns]"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The steps above are provided as built-in functionality of `read_csv`:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"data = pd.read_csv(\"data/flowdata.csv\", index_col=0, parse_dates=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
"<b>REMEMBER</b>: <br><br>\n",
"\n",
"`pd.read_csv` provides a lot of built-in functionality to support this kind of transactions when reading in a file! Check the help of the read_csv function...\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The DatetimeIndex"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"When we ensure the DataFrame has a `DatetimeIndex`, time-series related functionality becomes available:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"DatetimeIndex(['2009-01-01 00:00:00', '2009-01-01 03:00:00',\n",
" '2009-01-01 06:00:00', '2009-01-01 09:00:00',\n",
" '2009-01-01 12:00:00', '2009-01-01 15:00:00',\n",
" '2009-01-01 18:00:00', '2009-01-01 21:00:00',\n",
" '2009-01-02 00:00:00', '2009-01-02 03:00:00',\n",
" ...\n",
" '2012-12-31 21:00:00', '2013-01-01 00:00:00',\n",
" '2013-01-01 03:00:00', '2013-01-01 06:00:00',\n",
" '2013-01-01 09:00:00', '2013-01-01 12:00:00',\n",
" '2013-01-01 15:00:00', '2013-01-01 18:00:00',\n",
" '2013-01-01 21:00:00', '2013-01-02 00:00:00'],\n",
" dtype='datetime64[ns]', name='Time', length=11697, freq=None)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.index"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similar to a Series with datetime data, there are some attributes of the timestamp values available:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 1, 1, ..., 1, 1, 2], dtype=int32)"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.index.day"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 1, 1, ..., 1, 1, 2], dtype=int32)"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.index.dayofyear"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"array([2009, 2009, 2009, ..., 2013, 2013, 2013], dtype=int32)"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.index.year"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `plot` method will also adapt it's labels (when you zoom in, you can see the different levels of detail of the datetime labels):\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecde1014a8>"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have to much data to sensibly plot on one figure. Let's see how we can easily select part of the data or aggregate the data to other time resolutions in the next sections."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Selecting data from a time series"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use label based indexing on a timeseries as expected:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 09:00:00</th>\n",
" <td>0.330750</td>\n",
" <td>0.293583</td>\n",
" <td>0.029750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 12:00:00</th>\n",
" <td>0.295000</td>\n",
" <td>0.285167</td>\n",
" <td>0.031750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 15:00:00</th>\n",
" <td>0.301417</td>\n",
" <td>0.287750</td>\n",
" <td>0.031417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 18:00:00</th>\n",
" <td>0.322083</td>\n",
" <td>0.304167</td>\n",
" <td>0.038083</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2012-01-01 09:00:00 0.330750 0.293583 0.029750\n",
"2012-01-01 12:00:00 0.295000 0.285167 0.031750\n",
"2012-01-01 15:00:00 0.301417 0.287750 0.031417\n",
"2012-01-01 18:00:00 0.322083 0.304167 0.038083"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data[pd.Timestamp(\"2012-01-01 09:00\"):pd.Timestamp(\"2012-01-01 19:00\")]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"But, for convenience, indexing a time series also works with strings:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 09:00:00</th>\n",
" <td>0.330750</td>\n",
" <td>0.293583</td>\n",
" <td>0.029750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 12:00:00</th>\n",
" <td>0.295000</td>\n",
" <td>0.285167</td>\n",
" <td>0.031750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 15:00:00</th>\n",
" <td>0.301417</td>\n",
" <td>0.287750</td>\n",
" <td>0.031417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 18:00:00</th>\n",
" <td>0.322083</td>\n",
" <td>0.304167</td>\n",
" <td>0.038083</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2012-01-01 09:00:00 0.330750 0.293583 0.029750\n",
"2012-01-01 12:00:00 0.295000 0.285167 0.031750\n",
"2012-01-01 15:00:00 0.301417 0.287750 0.031417\n",
"2012-01-01 18:00:00 0.322083 0.304167 0.038083"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data[\"2012-01-01 09:00\":\"2012-01-01 19:00\"]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"A nice feature is **\"partial string\" indexing**, where we can do implicit slicing by providing a partial datetime string.\n",
"\n",
"E.g. all data of 2013:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2013-01-01 00:00:00</th>\n",
" <td>1.688333</td>\n",
" <td>1.688333</td>\n",
" <td>0.207333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 03:00:00</th>\n",
" <td>2.693333</td>\n",
" <td>2.693333</td>\n",
" <td>0.201500</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 06:00:00</th>\n",
" <td>2.220833</td>\n",
" <td>2.220833</td>\n",
" <td>0.166917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 09:00:00</th>\n",
" <td>2.055000</td>\n",
" <td>2.055000</td>\n",
" <td>0.175667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 21:00:00</th>\n",
" <td>0.898250</td>\n",
" <td>0.898250</td>\n",
" <td>0.077167</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-02 00:00:00</th>\n",
" <td>0.860000</td>\n",
" <td>0.860000</td>\n",
" <td>0.075000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>9 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2013-01-01 00:00:00 1.688333 1.688333 0.207333\n",
"2013-01-01 03:00:00 2.693333 2.693333 0.201500\n",
"2013-01-01 06:00:00 2.220833 2.220833 0.166917\n",
"2013-01-01 09:00:00 2.055000 2.055000 0.175667\n",
"... ... ... ...\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"2013-01-01 21:00:00 0.898250 0.898250 0.077167\n",
"2013-01-02 00:00:00 0.860000 0.860000 0.075000\n",
"\n",
"[9 rows x 3 columns]"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['2013']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Normally you would expect this to access a column named '2013', but as for a DatetimeIndex, pandas also tries to interprete it as a datetime slice."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Or all data of January up to March 2012:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 00:00:00</th>\n",
" <td>0.307167</td>\n",
" <td>0.273917</td>\n",
" <td>0.028000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 03:00:00</th>\n",
" <td>0.302917</td>\n",
" <td>0.270833</td>\n",
" <td>0.030583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 06:00:00</th>\n",
" <td>0.331500</td>\n",
" <td>0.284750</td>\n",
" <td>0.030917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 09:00:00</th>\n",
" <td>0.330750</td>\n",
" <td>0.293583</td>\n",
" <td>0.029750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-03-31 12:00:00</th>\n",
" <td>0.098333</td>\n",
" <td>0.124417</td>\n",
" <td>0.011833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-03-31 15:00:00</th>\n",
" <td>0.091917</td>\n",
" <td>0.123917</td>\n",
" <td>0.011500</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-03-31 18:00:00</th>\n",
" <td>0.085750</td>\n",
" <td>0.121417</td>\n",
" <td>0.011000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-03-31 21:00:00</th>\n",
" <td>0.068417</td>\n",
" <td>0.119750</td>\n",
" <td>0.010417</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>728 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2012-01-01 00:00:00 0.307167 0.273917 0.028000\n",
"2012-01-01 03:00:00 0.302917 0.270833 0.030583\n",
"2012-01-01 06:00:00 0.331500 0.284750 0.030917\n",
"2012-01-01 09:00:00 0.330750 0.293583 0.029750\n",
"... ... ... ...\n",
"2012-03-31 12:00:00 0.098333 0.124417 0.011833\n",
"2012-03-31 15:00:00 0.091917 0.123917 0.011500\n",
"2012-03-31 18:00:00 0.085750 0.121417 0.011000\n",
"2012-03-31 21:00:00 0.068417 0.119750 0.010417\n",
"\n",
"[728 rows x 3 columns]"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['2012-01':'2012-03']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>select all data starting from 2012</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2012-01-01 00:00:00</th>\n",
" <td>0.307167</td>\n",
" <td>0.273917</td>\n",
" <td>0.028000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 03:00:00</th>\n",
" <td>0.302917</td>\n",
" <td>0.270833</td>\n",
" <td>0.030583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 06:00:00</th>\n",
" <td>0.331500</td>\n",
" <td>0.284750</td>\n",
" <td>0.030917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2012-01-01 09:00:00</th>\n",
" <td>0.330750</td>\n",
" <td>0.293583</td>\n",
" <td>0.029750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 21:00:00</th>\n",
" <td>0.898250</td>\n",
" <td>0.898250</td>\n",
" <td>0.077167</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-02 00:00:00</th>\n",
" <td>0.860000</td>\n",
" <td>0.860000</td>\n",
" <td>0.075000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>2937 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2012-01-01 00:00:00 0.307167 0.273917 0.028000\n",
"2012-01-01 03:00:00 0.302917 0.270833 0.030583\n",
"2012-01-01 06:00:00 0.331500 0.284750 0.030917\n",
"2012-01-01 09:00:00 0.330750 0.293583 0.029750\n",
"... ... ... ...\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"2013-01-01 21:00:00 0.898250 0.898250 0.077167\n",
"2013-01-02 00:00:00 0.860000 0.860000 0.075000\n",
"\n",
"[2937 rows x 3 columns]"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['2012':]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>select all data in January for all different years</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01 00:00:00</th>\n",
" <td>0.137417</td>\n",
" <td>0.097500</td>\n",
" <td>0.016833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 03:00:00</th>\n",
" <td>0.131250</td>\n",
" <td>0.088833</td>\n",
" <td>0.016417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 06:00:00</th>\n",
" <td>0.113500</td>\n",
" <td>0.091250</td>\n",
" <td>0.016750</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 09:00:00</th>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 21:00:00</th>\n",
" <td>0.898250</td>\n",
" <td>0.898250</td>\n",
" <td>0.077167</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-02 00:00:00</th>\n",
" <td>0.860000</td>\n",
" <td>0.860000</td>\n",
" <td>0.075000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1001 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 00:00:00 0.137417 0.097500 0.016833\n",
"2009-01-01 03:00:00 0.131250 0.088833 0.016417\n",
"2009-01-01 06:00:00 0.113500 0.091250 0.016750\n",
"2009-01-01 09:00:00 0.135750 0.091500 0.016250\n",
"... ... ... ...\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"2013-01-01 21:00:00 0.898250 0.898250 0.077167\n",
"2013-01-02 00:00:00 0.860000 0.860000 0.075000\n",
"\n",
"[1001 rows x 3 columns]"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data[data.index.month == 1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>select all data in January, February and March for all different years</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" <th>months</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01 00:00:00</th>\n",
" <td>0.137417</td>\n",
" <td>0.097500</td>\n",
" <td>0.016833</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 03:00:00</th>\n",
" <td>0.131250</td>\n",
" <td>0.088833</td>\n",
" <td>0.016417</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 06:00:00</th>\n",
" <td>0.113500</td>\n",
" <td>0.091250</td>\n",
" <td>0.016750</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 09:00:00</th>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 21:00:00</th>\n",
" <td>0.898250</td>\n",
" <td>0.898250</td>\n",
" <td>0.077167</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-02 00:00:00</th>\n",
" <td>0.860000</td>\n",
" <td>0.860000</td>\n",
" <td>0.075000</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>2897 rows × 4 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348 months\n",
"Time \n",
"2009-01-01 00:00:00 0.137417 0.097500 0.016833 1\n",
"2009-01-01 03:00:00 0.131250 0.088833 0.016417 1\n",
"2009-01-01 06:00:00 0.113500 0.091250 0.016750 1\n",
"2009-01-01 09:00:00 0.135750 0.091500 0.016250 1\n",
"... ... ... ... ...\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333 1\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083 1\n",
"2013-01-01 21:00:00 0.898250 0.898250 0.077167 1\n",
"2013-01-02 00:00:00 0.860000 0.860000 0.075000 1\n",
"\n",
"[2897 rows x 4 columns]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data['months'] = data.index.month\n",
"data[data['months'].isin([1, 2, 3])]"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"data = data.drop(\"months\", axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>select all 'daytime' data (between 8h and 20h) for all days</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01 09:00:00</th>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 12:00:00</th>\n",
" <td>0.140917</td>\n",
" <td>0.096167</td>\n",
" <td>0.017000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 15:00:00</th>\n",
" <td>0.099167</td>\n",
" <td>0.091667</td>\n",
" <td>0.017583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 18:00:00</th>\n",
" <td>0.132667</td>\n",
" <td>0.090167</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 09:00:00</th>\n",
" <td>2.055000</td>\n",
" <td>2.055000</td>\n",
" <td>0.175667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 12:00:00</th>\n",
" <td>1.710000</td>\n",
" <td>1.710000</td>\n",
" <td>0.129583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5848 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 09:00:00 0.135750 0.091500 0.016250\n",
"2009-01-01 12:00:00 0.140917 0.096167 0.017000\n",
"2009-01-01 15:00:00 0.099167 0.091667 0.017583\n",
"2009-01-01 18:00:00 0.132667 0.090167 0.016250\n",
"... ... ... ...\n",
"2013-01-01 09:00:00 2.055000 2.055000 0.175667\n",
"2013-01-01 12:00:00 1.710000 1.710000 0.129583\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"\n",
"[5848 rows x 3 columns]"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data[(data.index.hour > 8) & (data.index.hour < 20)]"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01 09:00:00</th>\n",
" <td>0.135750</td>\n",
" <td>0.091500</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 12:00:00</th>\n",
" <td>0.140917</td>\n",
" <td>0.096167</td>\n",
" <td>0.017000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 15:00:00</th>\n",
" <td>0.099167</td>\n",
" <td>0.091667</td>\n",
" <td>0.017583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-01 18:00:00</th>\n",
" <td>0.132667</td>\n",
" <td>0.090167</td>\n",
" <td>0.016250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 09:00:00</th>\n",
" <td>2.055000</td>\n",
" <td>2.055000</td>\n",
" <td>0.175667</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 12:00:00</th>\n",
" <td>1.710000</td>\n",
" <td>1.710000</td>\n",
" <td>0.129583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 15:00:00</th>\n",
" <td>1.420000</td>\n",
" <td>1.420000</td>\n",
" <td>0.096333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2013-01-01 18:00:00</th>\n",
" <td>1.178583</td>\n",
" <td>1.178583</td>\n",
" <td>0.083083</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5848 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 09:00:00 0.135750 0.091500 0.016250\n",
"2009-01-01 12:00:00 0.140917 0.096167 0.017000\n",
"2009-01-01 15:00:00 0.099167 0.091667 0.017583\n",
"2009-01-01 18:00:00 0.132667 0.090167 0.016250\n",
"... ... ... ...\n",
"2013-01-01 09:00:00 2.055000 2.055000 0.175667\n",
"2013-01-01 12:00:00 1.710000 1.710000 0.129583\n",
"2013-01-01 15:00:00 1.420000 1.420000 0.096333\n",
"2013-01-01 18:00:00 1.178583 1.178583 0.083083\n",
"\n",
"[5848 rows x 3 columns]"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.between_time('08:00', '20:00')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"## The power of pandas: `resample`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A very powerfull method is **`resample`: converting the frequency of the time series** (e.g. from hourly to daily data).\n",
"\n",
"The time series has a frequency of 1 hour. I want to change this to daily:"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01</th>\n",
" <td>0.125010</td>\n",
" <td>0.092281</td>\n",
" <td>0.016635</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-02</th>\n",
" <td>0.124146</td>\n",
" <td>0.095781</td>\n",
" <td>0.016406</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-03</th>\n",
" <td>0.113562</td>\n",
" <td>0.085542</td>\n",
" <td>0.016094</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-04</th>\n",
" <td>0.140198</td>\n",
" <td>0.102708</td>\n",
" <td>0.017323</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-05</th>\n",
" <td>0.128812</td>\n",
" <td>0.104490</td>\n",
" <td>0.018167</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 0.125010 0.092281 0.016635\n",
"2009-01-02 0.124146 0.095781 0.016406\n",
"2009-01-03 0.113562 0.085542 0.016094\n",
"2009-01-04 0.140198 0.102708 0.017323\n",
"2009-01-05 0.128812 0.104490 0.018167"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.resample('D').mean().head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-danger\">\n",
"\n",
"<b>NOTE</b>:\n",
"\n",
" <ul>\n",
" <li>with older versions of pandas, <code>data.resample('D').mean()</code> was expressed as <code>data.resample('D', how='mean')</code>.</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Other mathematical methods can also be specified:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>L06_347</th>\n",
" <th>LS06_347</th>\n",
" <th>LS06_348</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Time</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2009-01-01</th>\n",
" <td>0.140917</td>\n",
" <td>0.097500</td>\n",
" <td>0.017583</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-02</th>\n",
" <td>0.147833</td>\n",
" <td>0.101917</td>\n",
" <td>0.016833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-03</th>\n",
" <td>0.135833</td>\n",
" <td>0.092500</td>\n",
" <td>0.016833</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-04</th>\n",
" <td>0.160417</td>\n",
" <td>0.113750</td>\n",
" <td>0.018417</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2009-01-05</th>\n",
" <td>0.161500</td>\n",
" <td>0.115167</td>\n",
" <td>0.021583</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" L06_347 LS06_347 LS06_348\n",
"Time \n",
"2009-01-01 0.140917 0.097500 0.017583\n",
"2009-01-02 0.147833 0.101917 0.016833\n",
"2009-01-03 0.135833 0.092500 0.016833\n",
"2009-01-04 0.160417 0.113750 0.018417\n",
"2009-01-05 0.161500 0.115167 0.021583"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.resample('D').max().head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
"<b>REMEMBER</b>: <br><br>\n",
"\n",
" The string to specify the new time frequency: http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases <br><br>\n",
" \n",
" These strings can also be combined with numbers, eg `'10D'`...\n",
"\n",
"</div>\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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qt7tAZyE8fe7DMYE4DthhH8RERERERERERERERERERERERERERERERERERERERERERERERERERERERH5Bb3x6Ld/EhEREZEWrqE7BdS2VQB+DeOuPb9qnl0UERERkaZken/QT2Hcks90mW7NJyIiItKK2cC4cXxdvfHgW8C1/QYDiAVwD8AhAP8VwEQAiTBuLr8NwN+ZrOdpAF8CSINxP/Aw6D7AIiIiIs3KBo8eACsAnADQEUBPAHcB+AFwBfAXGOGwHMBok/XsAhACoAeA/wSwCMaN4//YlAchIiIiIo/OBo8eAAkjxNX6Fsaonulbxr41ywHgtwAqATxXZ90BAD5v/C6LiIiIiDls8OgBsKROn9UAbtRZ5gTAvebnd2vWUVyn3YcxaigiIiIizcAGj/cZQFOrAFyts8wRwJGan0fDGAF8AcAf6rTfmLHPIiIiImIGGzy5APinmnX0MHcnRURERKTp2ODJBUAAcAaQAOB9AL8H0AWALYy3h0VERESkGdjgyQbAv4fxWcEEGN8iTofxGcH2jd1hERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERsZD/B6HwBj6jhodJAAAAAElFTkSuQmCC\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecddd11390>"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.resample('A').mean().plot() # 10D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>plot the monthly standard deviation of the columns</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdd3wUdf4/8Dflp2IZkWJDCRZAkbOd3VOxl9ND8c6vnpz1OKwnd3pG2n4Sem8iXUBQugISEFQ6JoFUEgghgSTU0EkCIaTt6/fHJyxZ2CS7GXdnZ3k9H495PMjM57PzDjvZvPKZmc+IEBEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREZFLHRFpJiIGFy5cuHDhwsVWSzPRv8eJfNZMRMCFCxcuXLhwseXSTIhqwRAR7Nq1C/n5+Vy4cOHChQsXGyy7du06FQANi3ME/c6+EP3GjqihXTsRSRSRYhHZJiJv+bgfQ0SQn58PIiIisof8/HwGwBB0t4hki8hGqT4AXicihSIyVERuFpGPRKRMRJ72YV8MgERERDbDABh6LhaRDBF5QkRWSfUBcKCIbDpj3SwRWerD/hgAiYiIbIYBMPR8IyLDK/69SqoPgGs8bH9bRPJ92B8DIBERkc0wAIaWV0UkVUQuqPh6lVQfADNEpOsZ654TfUA0qKLP+XL2LeQMgEREIcDpdKKkpARFRUVcbL6UlJTA6XRW+V4zAIaOa0Vkv4jcWmndKvn9A2CEeLiNnAGQiMjeiouLkZOTg7S0NC4hsuTk5KC4uNjj+80AGDpeFP1GllVaICLOin/X89CnNqeAOQJIRBRiysvLkZ6ejszMTOTl5eHEiROWj2Bxqf1y4sQJ5OXlITMzE+np6SgvLz/rPWcADB2XiEjbM5Y4EZle8W9PBoo+ZVzZDOFNIERE55SioiKkpaWhsLDQ6lLod1RYWIi0tDQUFRWdtY0BMLStEvcRvv4iMq3S16emgRkkIjeJyAfCaWCIiM45pwKgp6BA9lXd+8oAGNpWiXsAnFqxrrJ2IpIkeiLo7cKJoImIzjkMgKGJAZD8iQGQiMjmGABDEwMg+RMDIBGRzdk5AL755pto3769x21FRUX44IMP0KhRI1x00UXo0KED9u3bd1a7qKgo3HPPPbjgggvQsGHDKl/vTIcOHcLTTz+Nq666Cueddx6uueYafPjhh1X+TszMzMTFF1+MSy+99KzvQTzMsNGmTRuv6qgKAyD5EwMgEZHNhWoAfO+993Dttddi+fLliI+Px3333YcHHnjArc28efNw2WWXYezYsdi6dSs2b96M2bNne7XvI0eOYMyYMYiLi0NOTg5+/fVXtG7dGq+99tpZbUtKSnDXXXfh2WefPSsA5uXlITc317Xs2rULjRo1glLKu/+EKjAAkj8xABIFgcyNv2Hd+E9wrOCo1aWQDYViAMzLy8P/+3//D3PnznWt27JlC0QEMTExAIDS0lI0a9YMkyZN+t3qGTlyJK655pqz1n/++efo2LEjpkyZclYAPNP8+fNRp04d5OTkmKqFAZD8iQGQKAgkDnwWUAbifhxndSlkQ56CgtPpRGFxqSVLdU+wOFNVAXD58uUQERw96v5HUfPmzTFs2DAAwPr16yEimDx5Mm6//XZceeWVeOaZZ5Camlqr/8c9e/bgkUceweuvv35WLddddx3y8/O9CoDPP/88nnzyyVrVUBkDIPkTAyBRENjU90FAGYidNcDqUsiGPAWFwuJShIVHWbIUFpd6XXtVAfC7777Deeedd9b6u+++G59//jkAYObMmRARNG/eHPPmzUN8fDxee+01NG7cGIcPH/a6hldffRUNGjSAiOCFF15w+388dOgQrr32WqxevRoAagyAe/bsQb169bw+DV0dBkDyJwZAoiCwtfddgDIQM91hdSlkQ+dqAPzuu+8gIhg/frxr+8mTJ9GkSROMG+f9aHpubi62bNmChQsXok2bNnj//fdd21566SWEh4e7vq4pAPbr1w+NGzeu8hFuvmAAJH9iACQKAlmRtwLKQPTkz60uhWzoXD0FvGLFCogI1q5d69bmnnvuQbdu3Xz5L3RZu3YtRAR79+4FAFx66aWoV6+ea6lbty5EBPXq1cPXX3/t1tfpdOLGG29Ely5darXvMzEAkj8xABIFgV0RrXUAHP+x1aWQDYXyTSDz5s1zrUtPT3e7CSQ/Px/nn3++200gJSUluPzyy91GBX2xevVqiAiys7MBAGlpaUhNTXUtffr0wSWXXILU1FQcOXLEre/KlSshIrW+BvFMDIDkTwyAREFgv2qhTwF/9U+rSyEbsnsAbNeuHZKSktyWnTt34r333kPz5s2xYsUKxMfH4/7778f999/v1v+TTz5Bs2bNsGzZMqSnp+Pdd9/F5ZdfflY482Tx4sWYPHkyUlNTkZ2djaioKNx888148MEHq+xT3Sngjh074t577/XtP6AaDIDkTwyAREHgqLpa3wQysqPVpZAN2T0AiodJlN99913XRNCXXXYZLrzwQrz00kvIzc11619SUoJPP/0Ul19+OS655BI88cQT2LRpk1f7XrFiBe6//35ceumluOCCC9CyZUuEh4efddq5sqoCYF5eHho0aIAJEyb49h9QDQZA8icGQKIgcMLRRE8DM/Rlq0shG7JzAKSqMQCSPzEAElnMWV4OKANQBhIGPW91OWRDDIChiQGQ/IkBkMhiRSeOuwJg8oAnrC6HbIgB0LPOnTvjoosu8rh07tzZ6vJqxABI/sQASGSxvMMHXAFwU98/WV0O2RADoGf79+9HZmamx2X//v1Wl1cjBkDyJwZAIosd2JPtCoDpve+2uhyyIQbA0MQASP7EAEhksd3bN7kC4PbIW60uh2yIATA0MQCSPzEAElksa/MGVwDcFdHa6nLIhhgAQxMDIPkTAyCRxbYmrHIFwP2qhdXlkA0xAIYmBkDyJwZAIottjl7iCoB56iqryyEbYgAMTQyA5E8MgEQW27hynisAFjkaW10O2RADYGhiACR/YgAksljC0umuAAhloLyszOqSyGYYAEMTAyD5EwMgkcXiFo13C4AnjhdYXRLZjJ0D4Jtvvon27dt73JacnIwXXngBTZs2xfnnn4+wsDC88sorbnP47dixA8899xwaNGiApk2b4rPPPkNpaanb6zidTgwePBgtW7bEeeedh6uvvhp9+vTxqr61a9figQceQKNGjXDBBRegdevWGDZsWJXtZ86cCRE563sKCwvz+MzjDz74oMrXYgAkf2IAJLLY+u9HuAXAowdza+5EVEkoBsADBw6gcePGePPNN5GYmIisrCysWLECXbp0QVZWFgCgrKwMbdu2xRNPPIGkpCQsWbIETZo0QdeuXd1e6+OPP0br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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecddcbff60>"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.resample('M').std().plot() # 'A'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>plot the monthly mean and median values for the years 2011-2012 for 'L06_347'<br><br></li>\n",
"</ul>\n",
" \n",
" **Note** <br>You can create a new figure with `fig, ax = plt.subplots()` and add each of the plots to the created `ax` object (see documentation of pandas plot function)\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdeXxU5b0/8O9tf9araOqtV21r63GtaNH21lrbaku1VrG1tFqs1uLW3raittXb5QCiAYIgyCYgq4AgKIvI4kkIJBB2CDsECFkgQCAQQkhC9mRmPr8/npmTbbYzZ7ZMPu/Xa16vMnPmnMcyh/nMOc/z/YoQERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERkek/RORaEUnigw8++OCDDz461eNaUd/jRJZdKyLggw8++OCDDz465eNaIQpBkoiguLgYVVVVfPDBBx988MFHJ3gUFxd7AmBSjHMEdVJJIoKqqioQERFR51BVVcUASLYwABIREXUyDICJ5cci8pmIlIj6S/11EO/5iYjsFpFGESkUkectHpMBkIiIqJNhAEwsj4jIMBF5TIILgDeISK2IjBGR20TkFRFxiMjDFo7JAEhERNTJMAAmrmAC4EgROdDuuQUikm7hOAyAREQEAHC5XGhqakJ9fT0fMX40NTXB5XL5/LtiAExcwQTADSIyvt1zL4hIlZ/3XCwdawgxABIRdXGNjY04duwYDh06xEecPI4dO4bGxkavf18MgIkrmACYLyID2j33c/d7L/HxnsHipY4QAyARUdfldDpx+PBhFBQUoLKyEnV1dTG/AtaVH3V1daisrERBQQEOHz4Mp9PZ4e+MATBxRSoA8gogERG1UV9fj0OHDqG2tjbWQ6FWamtrcejQIdTX13d4jQEwcUXqFnB7nANIRNTFeQKgt6BBsePv74UBMHEFuwgkp91zHwkXgRARkQUMgPGJAbDruExEvu1+QERec//v69yvjxCRua2295SBGSUi3UXkJWEZGCIisogBMD4xAHYdPxHvjZ4/cL/+gYis8/KePaIKQR8RFoImIiKLGADjEwMgRRIDIBFRF8cAGJ8YACmSkkQElZWVMfhoExFRPOjMAbBnz5545ZVX8Pe//x1XXHEFrr76akyfPh01NTV4/vnncdlll+Gmm25CWlqa+Z6cnBz06tUL3bp1w9VXX42+ffuirKzMfH3lypW499578cUvfhFf+tKX8Itf/AKFhYXm60VFRRARLFmyBD/5yU9wySWX4M4778SWLVvC+t/GAEiRlCQiOFl6LqwfWiIi6jzaBw2Xy4XaxuaYPPx1v/CmZ8+euPzyy5GSkoL8/HykpKTg85//PB555BFMnz4d+fn56NevH6688krU1taioqICV111FQYMGIDc3Fzs3r0bP/vZz3D//feb+/zkk0+wZMkSFBQUYM+ePfjlL3+JO+64w6zH5wmA3bt3h2EYyMvLQ58+faBpGpqbmyP299IaAyDZlSQi2F14KmwfWCIi6lzaB43axmZouhGTR22jtQDVs2dP3HfffeafHQ4HunXrhmeeecZ87vTp0xARbN26FSkpKXjooYfa7KO4uBgigry8PK/HKCsrg4ggJycHQEsAfP/9981tDh48CBFBbm6upfH7wwBIkZQkIli9+2jYPrBERNS5dPYA+NJLL7V57rrrrsOoUaPMP7tcLogIli9fjj59+uCiiy5Ct27d2jxExLxNnJ+fj6eeego33HADLr/8cvP11NRUAC0BcPv27eYxzp8/DxHB+vXrQ/o78IYBkCIpSUQwf0P4frEQEVHn0tlvAf/9739v85ymaRg3blyb50QES5cuRa9evfD444+joKCgw6OmpgYAcOutt+Khhx5CZmYmDh06hAMHDpjvB1oC4J49e8z9V1RUQESQlZVl9f9+nxgAKZKSRATjUvd4+egREVFX0NkXgVgJgAMHDsStt97qc67euXPnICLYsGGD+dzGjRsZACnhJIkIBi7MDtsHloiIOpeuFABPnTqFq666Cn369MH27dtRWFiI9PR0PP/883A4HHA6nbjyyivRt29fFBQUYM2aNbj77rsZACnhJIkI/jQjfHMWiIioc+lKARBQc/wee+wxXHHFFbjkkkvQvXt3vPrqq+bt54yMDNx22224+OKLceedd2LdunUMgJRwkkQEvx6bEbYPLBERdS6dOQAmMgZAiqQkEcG9Qz+LwUebiIjiAQNgfGIApEhKEhHc8q9PLK+8IiKixMAAGJ8YACmSkkQEX391ES7UN8Xg401ERLHGABifGAApkswAWFBaHYOPNxERxRoDYHxiAKRIMgPg5oIyLx8/IiJKdAyA8YkBkCLJDIBLd5+MwcebiIhijQEwPjEAUiSZAXDqusIYfLyJiCjWGADjEwMgRZIZAIesOBiDjzcREcUaA2B8YgCkSDID4Mvzd8Xg401ERLHGABifGAApkswA+MSULTH4eBMRUawxAAbWvuWct3Zz4cYASJFkBsCeo9ZG9INMRETxiQEwsPYB8OzZs6itrY3oMRkAKZLMANh90Ep2AyEi6oIYAANrHwCjgQGQIskMgJpuoIrdQIiIupzOHAB79uyJV155BX//+99xxRVX4Oqrr8b06dNRU1OD559/HpdddhluuukmpKWlme/JyclBr1690K1bN1x99dXo27cvyspaauHW1NTgmWeeQbdu3fDlL38Zo0ePDngLeMyYMejRowcuvfRSfO1rX0O/fv1QXd3SYGH27Nn44he/iPT0dHTv3h3dunXDww8/jJKSEp//bQyAFElJIoLb+i+BphvsBkJE1AV1CBouF9BYE5uHxTtRPXv2xOWXX46UlBTk5+cjJSUFn//85/HII49g+vTpyM/PR79+/XDllVeitrYWFRUVuOqqqzBgwADk5uZi9+7d+NnPfob777/f3Ge/fv1w3XXXITMzE/v378ejjz6Kyy+/3G8AHDduHNauXYuioiKsWbMGt956K/r162e+Pnv2bFx00UV48MEHsWPHDuzatQu33XYbnn766eD/XlphACS7kkQEPx5mQNMNdgMhIuqCOgSNxhogOSk2j8YaS2Pv2bMn7rvvPvPPDocD3bp1wzPPPGM+d/r0aYgItm7dipSUFDz00ENt9lFcXAwRQV5eHqqrq/GFL3wBixYtMl8vLy/HJZdcYmkRyOLFi3HllVeaf549ezZEBIWFLTV333vvPVxzzTU+98EASJGUJCLo824mNN1gNxAioi6oswfAl156qc1z1113HUaNGmX+2eVyQUSwfPly9OnTBxdddBG6devW5iEiSEtLw969eyEiOH78eJt9fvvb3/YbADMyMvDAAw/gq1/9Ki677DL853/+J0TEXCgye/ZsXHrppW32+emnn+I/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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x7fecddc3f630>"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"data.loc['2011':'2012', 'L06_347'].resample('M').mean().plot(ax=ax)\n",
"data.loc['2011':'2012', 'L06_347'].resample('M').median().plot(ax=ax)\n",
"ax.legend([\"mean\", \"median\"])"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
},
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzdeXxU5b0/8O9tf9araOqtV21r63GtaNH21lrbaku1VrG1tFqs1uLW3raittXb5QCiAYIgyCYgq4AgKIvI4kkIJBB2CDsECFkgQCAQQkhC9mRmPr8/npmTbbYzZ7ZMPu/Xa16vMnPmnMcyh/nMOc/z/YoQERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERkek/RORaEUnigw8++OCDDz461eNaUd/jRJZdKyLggw8++OCDDz465eNaIQpBkoiguLgYVVVVfPDBBx988MFHJ3gUFxd7AmBSjHMEdVJJIoKqqioQERFR51BVVcUASLYwABIREXUyDICJ5cci8pmIlIj6S/11EO/5iYjsFpFGESkUkectHpMBkIiIqJNhAEwsj4jIMBF5TIILgDeISK2IjBGR20TkFRFxiMjDFo7JAEhERNTJMAAmrmAC4EgROdDuuQUikm7hOAyAREQEAHC5XGhqakJ9fT0fMX40NTXB5XL5/LtiAExcwQTADSIyvt1zL4hIlZ/3XCwdawgxABIRdXGNjY04duwYDh06xEecPI4dO4bGxkavf18MgIkrmACYLyID2j33c/d7L/HxnsHipY4QAyARUdfldDpx+PBhFBQUoLKyEnV1dTG/AtaVH3V1daisrERBQQEOHz4Mp9PZ4e+MATBxRSoA8gogERG1UV9fj0OHDqG2tjbWQ6FWamtrcejQIdTX13d4jQEwcUXqFnB7nANIRNTFeQKgt6BBsePv74UBMHEFuwgkp91zHwkXgRARkQUMgPGJAbDruExEvu1+QERec//v69yvjxCRua2295SBGSUi3UXkJWEZGCIisogBMD4xAHYdPxHvjZ4/cL/+gYis8/KePaIKQR8RFoImIiKLGADjEwMgRRIDIBFRF8cAGJ8YACmSkkQElZWVMfhoExFRPOjMAbBnz5545ZVX8Pe//x1XXHEFrr76akyfPh01NTV4/vnncdlll+Gmm25CWlqa+Z6cnBz06tUL3bp1w9VXX42+ffuirKzMfH3lypW499578cUvfhFf+tKX8Itf/AKFhYXm60VFRRARLFmyBD/5yU9wySWX4M4778SWLVvC+t/GAEiRlCQiOFl6LqwfWiIi6jzaBw2Xy4XaxuaYPPx1v/CmZ8+euPzyy5GSkoL8/HykpKTg85//PB555BFMnz4d+fn56NevH6688krU1taioqICV111FQYMGIDc3Fzs3r0bP/vZz3D//feb+/zkk0+wZMkSFBQUYM+ePfjlL3+JO+64w6zH5wmA3bt3h2EYyMvLQ58+faBpGpqbmyP299IaAyDZlSQi2F14KmwfWCIi6lzaB43axmZouhGTR22jtQDVs2dP3HfffeafHQ4HunXrhmeeecZ87vTp0xARbN26FSkpKXjooYfa7KO4uBgigry8PK/HKCsrg4ggJycHQEsAfP/9981tDh48CBFBbm6upfH7wwBIkZQkIli9+2jYPrBERNS5dPYA+NJLL7V57rrrrsOoUaPMP7tcLogIli9fjj59+uCiiy5Ct27d2jxExLxNnJ+fj6eeego33HADLr/8cvP11NRUAC0BcPv27eYxzp8/DxHB+vXrQ/o78IYBkCIpSUQwf0P4frEQEVHn0tlvAf/9739v85ymaRg3blyb50QES5cuRa9evfD444+joKCgw6OmpgYAcOutt+Khhx5CZmYmDh06hAMHDpjvB1oC4J49e8z9V1RUQESQlZVl9f9+nxgAKZKSRATjUvd4+egREVFX0NkXgVgJgAMHDsStt97qc67euXPnICLYsGGD+dzGjRsZACnhJIkIBi7MDtsHloiIOpeuFABPnTqFq666Cn369MH27dtRWFiI9PR0PP/883A4HHA6nbjyyivRt29fFBQUYM2aNbj77rsZACnhJIkI/jQjfHMWiIioc+lKARBQc/wee+wxXHHFFbjkkkvQvXt3vPrqq+bt54yMDNx22224+OKLceedd2LdunUMgJRwkkQEvx6bEbYPLBERdS6dOQAmMgZAiqQkEcG9Qz+LwUebiIjiAQNgfGIApEhKEhHc8q9PLK+8IiKixMAAGJ8YACmSkkQEX391ES7UN8Xg401ERLHGABifGAApkswAWFBaHYOPNxERxRoDYHxiAKRIMgPg5oIyLx8/IiJKdAyA8YkBkCLJDIBLd5+MwcebiIhijQEwPjEAUiSZAXDqusIYfLyJiCjWGADjEwMgRZIZAIesOBiDjzcREcUaA2B8YgCkSDID4Mvzd8Xg401ERLHGABifGAApkswA+MSULTH4eBMRUawxAAbWvuWct3Zz4cYASJFkBsCeo9ZG9INMRETxiQEwsPYB8OzZs6itrY3oMRkAKZLMANh90Ep2AyEi6oIYAANrHwCjgQGQIskMgJpuoIrdQIiIupzOHAB79uyJV155BX//+99xxRVX4Oqrr8b06dNRU1OD559/HpdddhluuukmpKWlme/JyclBr1690K1bN1x99dXo27cvyspaauHW1NTgmWeeQbdu3fDlL38Zo0ePDngLeMyYMejRowcuvfRSfO1rX0O/fv1QXd3SYGH27Nn44he/iPT0dHTv3h3dunXDww8/jJKSEp//bQyAFElJIoLb+i+BphvsBkJE1AV1CBouF9BYE5uHxTtRPXv2xOWXX46UlBTk5+cjJSUFn//85/HII49g+vTpyM/PR79+/XDllVeitrYWFRUVuOqqqzBgwADk5uZi9+7d+NnPfob777/f3Ge/fv1w3XXXITMzE/v378ejjz6Kyy+/3G8AHDduHNauXYuioiKsWbMGt956K/r162e+Pnv2bFx00UV48MEHsWPHDuzatQu33XYbnn766eD/XlphACS7kkQEPx5mQNMNdgMhIuqCOgSNxhogOSk2j8YaS2Pv2bMn7rvvPvPPDocD3bp1wzPPPGM+d/r0aYgItm7dipSUFDz00ENt9lFcXAwRQV5eHqqrq/GFL3wBixYtMl8vLy/HJZdcYmkRyOLFi3HllVeaf549ezZEBIWFLTV333vvPVxzzTU+98EASJGUJCLo824mNN1gNxAioi6oswfAl156qc1z1113HUaNGmX+2eVyQUSwfPly9OnTBxdddBG6devW5iEiSEtLw969eyEiOH78eJt9fvvb3/YbADMyMvDAAw/gq1/9Ki677DL853/+J0TEXCgye/ZsXHrppW32+emnn+I//uM/gv97aYUBkOxKEhG8OHMDNN1gNxAioi6os98Cbr84w9vVORHB0qVL0atXLzz++OMoKCjo8KipqQkpABYVFeHiiy/Gq6++iq1btyIvLw8zZ86EiKCiogJAyxzA1pYuXQoRCf7vpRUGQLIrSUTw5uLt0HSD3UCIiLqgzr4IxEoAHDhwIG699VY0Nzd73V91dTUuuuiiNreAz58/j0svvdRnAPzkk09w0UUXwel0mq+npKQwAFJcSxIRTEzfB0032A2EiKgL6koB8NSpU7jqqqvQp08fbN++HYWFhUhPT8fzzz8Ph8MBAHjxxRehaRrWrFmDnJwc9O7dG5dddpnPAOi5ajh+/HgcOXIEc+fOxbXXXssASHEtSUSwYNNhaLrBbiBERF1QVwqAAJCfn4/HHnsMV1xxBS655BJ0794dr776qlkLt7q6Gn379sWll16Ka665BqNGjQpYBmbs2LH4yle+gksuuQQPP/ww5s6dywBIcS1JRLBmXxE03WA3ECKiLqgzB8BExgBIkZQkIth/tASabrAbCBFRF8QAGJ8YACmSkkQEp8vKoekGu4EQEXVBDIDxiQGQIilJRFBVVYUeyensBkJE1AUxAMYnBkCKJDMAPjA6i91AiIi6IAbA+MQASJFkBsDfTd/KbiBERF0QA2B8YgCkSDID4N8/3s1uIEREXZAnaNTV1cV6KNRKXV0dAyBFjBkAh6ceYjcQIqIuyOFw4NChQzh37lysh0KtnDt3DocOHTILVLfGAEh2mQHw/Y1H2Q2EiKiLKikpMUNgXV0d6uvr+YjRo66uzgx/JSUlXv++GADJLjMArth7it1AiIi6KJfLZYZAPuLjUVJS4rM2LwMg2WUGwOyj5ewGQkTUxTkcjphfAeOj3utt39YYAMkuMwAWldWwGwgREVEnwABIdpkBsLaxmd1AiIiIOgEGQLLLDIAA2A2EiIioE2AAJLvaBEB2AyEiIop/DIBkV5sA6OkG8unu4hh/tImIiMgXBkCyq00AZDcQIiKi+McASHa1CYDsBkJERBT/GADJrjYBkN1AiIiI4h8DINnVJgCyGwgREVH8YwAku9oEQE83kB+zGwgREVHcYgAku9oEwGPn2A2EiIgo3jEAkl1tAmBdo4PdQIiIiOIcAyDZ1SYAAuwGQkREFO8YAMmuDgGQ3UCIiIjiGwMg2dUhALIbCBERUXxjACS7OgTAVxfsYTcQIiKiOOVyufCb8ZkMgGRLhwDIbiBERETxq7KuCV9/dREDINnSIQCyGwgREVH8OlpWwwBItnUIgOwGQkREFL92FJUzAJJtHQIgu4EQERHFr/QDpxkAybYOAZDdQIiIiOLXR9nHGQAT0MsickxEGkQkW0S+F2D734vIPhGpE5HTIjJLRK60cLwOAZDdQIiIiOLXxDX5DIAJ5kkRaRSRF0TkdhGZLiIVInK1j+3vFRGniPxNRG4QkftE5ICIfGrhmB0CIMBuIERERPFq8IoDDIAJJltEJrX68+dE5JSI9Pex/T9F5Ei75/4qIictHNNrAGQ3ECIiovj01492MwAmkC+IiENEft3u+TkistzHe+4VkSYR+bmI/IeIXCMiG0RdOfTlYlEfFs/jWvESANkNhIiIKD79fsY2BsAE8lVRf5E/aPf8KFFXBn15QkSqRaTZ/f4VInKRn+0Hu7dr82gfANkNhIiIKD49PG49A2ACCSUA3i4iJSLyLxG5U0QeFpH9IjLTz3GCugLIbiBERETx6e5hGQyACSSUW8Afisgn7Z67T9QH4itBHtfrHEB2AyEiIoo/LpcLNw1IZQBMMNkiMrHVnz8nakGHr0UgS0RkQbvnfiDqA/HVII/pNQCyGwgREVH8qaxtgqYbDIAJ5klR9f+eE5HbRGSaqDIw17hfHyEic1tt/7youX/9RORGUYtCdoj/OYPteQ2A7AZCREQUfwrPVkPTDdzWfwkDYIJ5RUSOi6oHmC0i97R67QMRWddu+7+KyEFRhaBLRGSeqHl9wfIaANkNhIiIKP5sL1IXaO4d+hkDINniNQCyGwgREVH8WZlTAk038MsxqxkAyRavARBo3Q3kQgw+4kRERNTevG3HoOkGnp2axQBItvgMgOwGQkREFF/ezcyHpht47cPNDIBki88AyG4gRERE8SV5+QFouoGhS3YwAJItPgMgu4EQERHFl5fn74KmG5iUvo8BkGzxGQDZDYSIiCi+eO7OfbQxlwGQbPEZAD3dQF5iNxAiIqK48NDY9dB0A+m7jzIAki0+AyC7gRAREcWXu1IyoOkGsg8XMwCSLT4DILuBEBERxQ+n04UbB6RC0w0UFpcyAJItPgMgu4EQERHFj/M1jWaThnPnKxgAyRafAZDdQIiIiOJHQekFaLqBO5LTUVVVxQBItvgMgAC7gRAREcWLbUfOQdMN3P9OFgMg2eY3ALIbCBERUXxI3a/6AP9m8mYGQLLNbwBkNxAiIqL4MHer6gP857k7GADJNr8BkN1AiIiI4sO4jDxouoH+S/YzAJJtfgMgu4EQERHFhzeW5UDTDYxedZgBkGzzGwDZDYSIiCg+vDRP9QGetekoAyDZ5jcAfraP3UCIiIjiwZPTtkDTDSzfe4oBkGzzGwDZDYQovqzYewr/WLQXDc2OWA+FiKLswTHroOkGNhWUMQCSbX4DILuBEMWX+92lmdIPnI71UIgoyr4zdDU03UDu6SoGQLLNbwBkNxCi+PLNN1Vx9rGr82I9FCKKIofThev7q+/j0gv1DIBkm98ACLAbCFG8aP2D7E9zdsR6OEQUReeqG8zzv9nhZAAk2wIGwJ+65xywGwhRbJ0orzW/AO4buSbWwyGiKMo7o/oAf2vIKgBgACTbAgZAdgMhig87j503A6CmG7jAaRlEXcaWQtUH+IHRWQAYAMm+gAHQ0w1kCruBEMXUypzTbQLg9qLyWA+JiKKkfVk2BkCyK2AAZDcQovjg6QPqeczZUhTrIRFRlMzZUgRNN/DihzsBMACSfQEDILuBEMWHMavz2gTA/kv2xXpIRBQlnvN/4Kf7ATAAkn0BAyC7gRDFhwGf7oemG2Yx2N6TNsV6SEQUJa8vVef/GHcJKAZAsitgAGQ3EKL48L9zdkDTDQz97CA03cCtg9LgcLJAO1FX8OKHO6HpBj7YXASAAZDsCxgAPd1Abh2Uxm4gRDH0q0mboOkGVuaU4NZBadB0A4Vnq2M9LCKKgiemqj7An+07BYABkOwLGADZDYQoPvxwxBpouoFdx8+jtzsMer4MiCixPeBuA7m5UNXkZQAkuwIGQIDdQIhizeVy4ZbX1VW/E+W16L9kHzTdwMiVubEeGhFFwbeHrIKmG8g7o76HGQDJrqACILuBEMVWZV2TeSW+vslhloR4flZ2rIdGRBHW7HCa539ZdQMABkCyL6gAyG4gRLFVeLYamm6gR3I6AGB7kVqcdc9bmTEeGRFF2tkLqg/w9f0Nc+EXAyDZFVQAZDcQotjaekS1gbrf3QbqQn3LFcHzNY2xHRwRRVTu6SpouoH/GbrafI4BkOwKKgCyGwhRbK3Y667HObWlHud9I9dwagZRF7C5oMysAerBAEh2BRUA2Q2EKLZmejkH/+SuCzhjw5EYjoyIIs3zA/C3rX4AMgCSXUEFQHYDIYqtt1fmQtMNJC8/YD431t0a6v8W7o3hyIgo0mZvcv8AnNfyA5ABkOwKKgCyGwhRbP1j0V5ouoFJawvM59IPnIamG3hk/IYYjoyIIm3MqsPQdAODluaYzzEAkl1BBUB2AyGKredmZUPTDSzcccJ87kR5LTTdwC0D09DkcMZwdEQUSZ4+4OMy8sznGADJrqACILuBEMXWz9/dAE03sPZwqfmcy+VCjzdVkfbc0/7PYSLqvP4yV/UBnrulyHyOAZDsCioAAuwGQhRLdw/LgKYbyDlZ2eb5PlM2s0YnUYLznOep+0vM5xgAya6gAyC7gRDFhsPpwo0DUqHpBs5U1bd57Y1lOdB0A8MMlmgiSlT3u/sAbz1yznyOAZDsCjoAshsIUWyUVbd0AWg/1++j7OPQdAO/n7EtRqMjoki7c/CqDnfgGADJrqADILuBEMWGpwvAd1p1AfDYc6LCfI0LtIgST1OrPsDlrbr+MACSXUEHQHYDIYqNDflnoekGHh63vsNrdY0O3NBffTmUtrs9TESdX2lVPTTdwA39DTidLT/yGADJrqADILuBEMXGkl3F0HQDfd/3fpvXMz8oq9UKYSJKDIdK1B2Au1La3gFgACS7gg6A7AZCFBtT1xVC0w28umCP19dfmr8Lmm5gchanZxAlmo35qg/wQ2Pb3gFgACS7gg6A7AZCFBspnx2Epht4K/WQ19cnrS2Aphv460e7ozwyIoq0ZXtOQtMNPDVta5vnGQDJrqADILuBEMXG3z7eDU03MH39Ea+vr80thaYbeHDMuiiPjIgibaZ7+tXL7aZfMQCSXUEHQHYDIYqNp2eoEkxLd5/0+vrpSjVJ/MYBqahvckR5dEQUSe+kqz7Aby7LafM8AyDZFXQABNgNhCgWfjZWFWHf5KMIu8vlwreHqDph+4srvW5DRJ1T/yX7oOkG3s3Mb/M8AyDZZSkAerqB+PoiIqLw84S7vDO+f3h5CrUv3H4iiiMjokj705wd0HQDH2491uZ5BkCyy1IAZDcQouhqbPZeBLa9oe6FIsnLD0RxdEQUaY9PVn2AV+aUtHmeAZDsshQA2Q2EKLpKKuug6QZuGpDapghse4t3qlqBT0xlmSaiRPKTd1Sdz+yj5W2eZwAkuywFwOFp7AZCFE37ilWrt3veyvS73YFTldB0Az2S07lKnyiBeObeF56tbvM8AyDZZSkAshsIUXStyT0DTTfw6ISNfrdraHbgpgGp0HQDxedrozQ6Ioqk1lNAKmrbTgFhACS7LAVATzeQPlM2R+KzTkTtLNh+HJpu4IXZ2wNu+/C49dB0A6sPnonCyIgo0lqXeGo/BYQBkOyyFADZDYQouiauyYemG/jX4r0Bt/XM0W1fLoKIOifP1I7vDsvo8BoDINllKQCyGwhRdL25LAeabmBUem7AbaetVz2DX/xwZxRGRkSRtj7vLDTdwMPj1nd4jQGQ7LIUANkNhCi6+s3bCU03MHvT0YDbeprG9+QVeqKEsHS36gP89IytHV5jACS7LAVAgN1AiKKpzxRVA8zYVxJw23PVDdB0A9f3N1DT0ByF0RFRJM3YcASabuCVj3Z3eI0BMPG8LCLHRKRBRLJF5HsBtr9YRN4SkeMi0uh+7x8sHM9yAGQ3EKLo8VUDzJe7h2VA0w3sPHY+wiMjokgbuTLXZ4F3BsDE8qSoEPeCiNwuItNFpEJErvbznuUisk1EHhSR60XkByJyr4VjWg6A7AZCFD3ffFNdcT9aVhPU9s/OzPbaNoqIOp9/L1Z9gCd4WdjFAJhYskVkUqs/f05ETolIfx/b9xKRShH5ko1jWg6A7AZCFB21jc3mnNsLQc65HZGmrhgM/HR/hEdHRJH2xw9UH+D52453eI0BMHF8QUQcIvLrds/PEXWVz5vJIpIpIm+LCor5IjJaRC7xc5yLRX1YPI9rxWIAZDcQoug4fq7W8qr7ZXvUpPHH3tsU4dERUaT9+r1N7j7Apzu8xgCYOL4q6i/yB+2eHyXqyqA36aLmChqi5gr+XNQcwNl+jjPYfZw2DysBkN1AiKJj5zFVd/O+kWuCfk/+mQvQdAO3vbHSb+9gIop/Px61FppuYEdRxznADICJI5QAuFpE6kXki62ee1xEXOL7KqDtK4DsBkIUHStzTlu+mtfscOKW19MszRskovjkmQN8pF0fYIABMJGEcgt4jogUtnvuNlEfiFuCPK7lOYDsBkIUHXO3HoOmG/jz3B2W3vfohI3QdAOp+wOXjiGi+FTf1FJ3t7Ku4xxgBsDEki0iE1v9+XMiclJ8LwL5s4jUichlrZ77lYg4xf88wNYsB0B2AyGKjjGr86DpBl5fam1Bx78W74WmGxi96nCERkZEkXaqog6abuDmgalev2sZABPLk6Lm9D0n6kreNFFlYK5xvz5CROa22v4yESkWkcWiysb8WNRCkBkWjmk5ALIbCFF09F+yH5puYFxGnqX3zdqk5un+8YPtERoZEUVazknVB/h7b3XsAwwwACaiV6SlqHO2iNzT6rUPRGRdu+27i0iGqCuBxSIyRoK/+icSQgAE2A2EKBo8JSDmbbNW02/bkXPQdAM/HBH84hEiii9Zh0uh6QZ6jd/g9XUGQLIrpADIbiBEkdd7kioBsepAxxIQ/lTWNbXMHarlVXqizmjJrmJouoG+72/z+joDINkVUgBkNxCiyPvhiDXQdAO7j1tv6+Z579Yj5yIwMiKKtOnrVR/gv33csQ8wwABI9oUUANkNhCiyXC6XWc6l+Hyt5fd7bh/P2nQ0AqMjokjzdPXx1XSBAZDsCikAshsIUWS1vo1b3+Sw/P4xqw5D0w38a/HeCIyOiCLtn4vUav5Jawu8vs4ASHaFFADZDYQosgpKq6HpBnokp4f0/rT9JdB0A49O2BjmkRFRNPxh9nZouoGPszv2AQYYAMm+kAIgu4EQRdaWQrWS9/7RWSG9v6hM1eu85fU0NDuc4R0cEUVcoEVgDIBkV0gBkN1AiCJr+V71I+u3U7eE9H6n04Xb31gJTTeQd4blmog6m/tGqoVcO495XwTGAEh2hRQA2Q2EKLJmuqdZvGxjmsVj76krCMv2nAzjyIgoGm5z/4Ar8tHTmwGQ7AopALbuBuKtRyER2fP2SrUCcPCKAyHvY+CnqpPI8LRDYRwZEUVa6z7AF3x03GIAJLtCCoAAu4EQRdI/3CsA38vyvgIwGB9uPQZNN/DMzOwwjoyIIu2kuw/wLQN932VjACS7Qg6A7AZCFDnPzsyGphtYuONEyPvYdfw8NN3Ad4d57yVKRPFpX3EFNN3A94dn+tyGAZDsCjkAshsIUeQ8Mn4DNN3A2sOlIe+jtrEZ1/dXt5HKqhvCODoiiqS17j7AP3/Xex9ggAGQ7As5ALIbCFHkfHdYBjTdQM7JSlv7+ck7WdB0Axvyz4ZpZEQUaYt3FgecvsEASHaFHAA93UDsTFInoo4cThduHJAKTTdQWlVva1/95u2EphuYtp4/1Ig6i2nrC6HpBl5dsMfnNgyAZFfIAZDdQIgio6y6AZpu4Pr+hu0izhMy8wN+kRBRfBmeqi6wpHzmu90qAyDZFXIAZDcQosg4VFIFTTfwnaGrbe8r4+AZaLqBh8etD8PIiCgagqkCwABIdoUcANkNhCgy1uedDVto85STuGlAKhqaHWEYHRFF2vOz3FUAtvuuAsAASHaFHADZDYQoMj5xTwDv+/422/tyuVy4w12z0+6CEiKKjt4TN0LTDWQcPONzGwZAsivkAArYlCYAACAASURBVMhuIESRMXWdmgD+Wpjm7f126hZouoFFNmoKElH0/HCE6gO8+7j3PsAAAyDZF3IABNgNhCgSUj47qFq4pYanhVvy8gPQdANDVvieUE5E8aP7INUH+Pi5Wp/bMACSXbYCILuBEIXf3z7eDU03MGPDkbDsb+H2E9B0A09N2xqW/RFR5NQ2Npt312oamn1uxwBIdtkKgE/PYDcQonDzdNlZuvtkWPaXc7ISmm7gW0NWcb4uUZw7UV4LTTfwjdf9z69nACS7VAAsD61LALuBEIXfg2G+sl7f5DALS5dU1oVln0QUGXtOqD7APxyxxu92DIBklwqAB0Mr5cJuIETh960hq6DpBvLOhG9u7c/GqlC5Jtf3qkIiir01uap256MTNvrdjgGQ7FIBMOOdkD6o7AZCFF6NzU5z/s/5msaw7dczr3DSWt+FZYko9hbuUHN2n5vluw8wwABI9qkAOPupkD6o7AZCFF4llapw880DU+F0hm++3hR3aRn+WCOKb55z9bWF/stAMQCSXSoAvvWNkD6o24vYDYQonPYVq/k/3x+eGdb9rnN3F7l/dFZY90tE4TXMUGWg3gpQBooBkOxSAbD/5UCl9RWH7AZCFF6Zh4Kb/2NV6YV6aLqB6/sbqG30XVqCiGLrtYXBLa5kACS7WgLggaWWP6jsBkIUXh9nH4emG3hh9vaw7/uulNUBuwsQUWw9OzM7qM49DIBkV0sATB8Y0oeV3UCIwmdCZj403cC/F+8L+777vr8Nmm5g/rbjYd83EYXHoxM2BrVinwGQ7GoJgDMeDOnDym4gROHz5rIcaLqBd9IPh33fb6Wqsk2DluaEfd9EFB4/GJ4JTTew90SF3+0YAMmulgA49L+B5gbLH1Z2AyEKn37zdkLTDXywuSjs+/50dzE03cBvJnPVPlE8crlc+MbradB0AyfKffcBBhgAyT4VAIdoQHIScML6vCN2AyEKnz5TNkPTDaTuLwn7vg+fvgBNN/DNN9PDWmKGiMKjuqGlD3CgxVoMgGSXCoAzHlcBcMskyx9YdgMhCp+eo9ZC0w1kHy0P+76bHE7cMlBdXTh+zv/VBSKKvuPnVB/g7oNWBtyWAZDsUgFw5TAVABc+a/kDy24gROFz+xsroekGjpbVRGT/P393AzTdwMqc0xHZPxGFbtfx80H1AQYYAMk+FQD3rVQBcMxtlj+w7AZCFB61jS23f6obIlOr7x+L9kLTDYxdnReR/RNR6DIOqjqgvScGrgPKAEh2qQBYVgIM/i8VAi0WhPZ0A/nRSHYDIbKj9e2fSBVW91yx/9OcHRHZPxGFbsF2VQf0+QB9gAEGQLJPBcCqKmDKfSoAHvjU0geW3UCIwmPnscj/mNpcWAZNN3DfyMC3mIgout7LKoCmG/jHor0Bt2UAJLtaAqDxfyoAWiwIzW4gROGxMqcEmm7g8QiWaamobTTP1wv1PF+J4snQz1Qf4OEB+gADDIBkX0sA3LtABcAQCkKzGwiRfXO3FEHTDfx5bmRvz37fXWh2e1H4VxoTUeg8ZdWmrQ9cVo0BkOxqCYDnClUADKEgNLuBENk3ZtVhaLqB15fuj+hxXpi9PWLFpokodJ52jYt3Bm6swABIdrUEQJcLGHlDSAWhPd1AluxiNxCiUPVfsh+abmB8Rn5EjzMqPReabkD/JPz9hokodJ4yTWsPlwbclgGQ7GoJgAAw/8mQCkKzGwiRfX/8YAc03cD8bccjehxP6aZgSk0QUfTc85aanrGv2H8fYIABkOxrGwA3jA6pIDS7gRDZ13vSJmi6gdUHz0T0OEfOVpsr9x1sCUcUF1wul9mp52RFXcDtGQDJrrYB8OiGkApCsxsIkX0/HLEGmm5g9/HzET2Ow+lC90Er3Qu3qiN6LCIKTlV9k7lCv77JEXh7BkCyqW0AbKwJqSA0u4EQ2dP613/x+cj36f2V+2rjir2nIn4sIgqsqEzV1L39jcB9gAEGQLKvbQAEQioIzW4gRPZU1lr79W+XZ8HJyJW5ET8WEQXmKQQfbJF2BkCyq2MA9BSEXjkg6A8uu4EQ2VNQqubl3ZGcHpXjeWoOBtNyiogib9WB09B0A7+atCmo7RkAya6OATCEgtDsBkJkz5bCc9B0Aw+MzorK8Xa4r9rf81ZmVI5HRP59lK36AP9hdnBl2BgAya6OATDEgtDsBkIUuuV71TzaJ6dticrxqhuazR9t52sao3JMIvJt0lrVB/hfiwP3AQYYAMm+jgEwxILQ7AZCFDrPSvqXo7iS/kcj10LTDWzmOUsUc4NXHICmGxiRFty8XAZAsqtjAARCKgjNbiBEoRuRlhv1Wpp/nqsKT8/YcCRqxyQi7/728W5L52PV+XMMgGSL9wAYQkFodgMhCt3/LdwLTTfwXlZB1I45LiMPmm7gtYV7onZMIvLu9zO2BX8RxeVCVfLXGADJFu8BMISC0OwGQhS6Z2dmQ9MNLNpxImrHTHevOuw1fkPUjklE3vUar/oAr8s7G3jj88dQ1f9yBkCyxXsADKEgNLuBEIXuEfc//llBNIEPlxPltdB0AzcPTEVjszNqxyWiju4elgFNN5BzsjLwxofTGADJNu8BELBcEJrdQIhC9133P/4HTgXxj3+YuFwuc/X+oRIv/wYQUVS4XC7cPDAVmm6gpDJwH2CsH8UASLb5DoAWC0KzGwhRaBxOF27or0qylFbVR/XYT0zZwsVbRDFWWdfSCaihOYhOQIueZwAk23wHQLMg9E+D+gCzGwhRaM5eaICmG7i+v4FmR3Rvxb65LAeabmCYcTCqxyWiFkfOqk5APd4MshPQpO8xAJJtvgOgxYLQ7AZCFJqDp6qg6QbuSlkd9WN/7O4+8PsZ26J+bCJSPJ15fjwqiDtozQ3A4P9iACTbfAfAEApC38FuIESWrc87C0038PC49VE/9t4TFdB0A98ZuppX7oliZGWOWpH/2HtB9AEu2QckJ6Eq+VoGQLLFdwAELBeEZjcQIus+2VkMTTfQ9/3oX4Wrb3LEbP4hESnzt6kr8X/8YEfgjfd+rALgew8yACaYl0XkmIg0iEi2iHwvyPfdKyIOEdlr8Xj+A6DFgtDsBkJk3ZR1hTEtyPzA6Kyol6AhohYTMvOh6Qb0T/YF3njVIBUAF73CAJhAnhSRRhF5QURuF5HpIlIhIlcHeN8VInJERFZJuAOgxYLQ7AZCZN3Qzw5C0w0MTz0Uk+O/PH8XNN3A5Cyet0SxkLxc9QEeuTKIPsBzH1MBMGsSA2ACyRaRSa3+/DkROSUi/QO8b4GIpIjIYAl3ALRYEJrdQIis++tH1nqAhtuktQXQdAOvfLQ7Jscn6upecf8b8P7Go4E3Hn2rCoAH1zAAJogviLqF++t2z88RkeV+3veCiGwXkf8nkQiAgKWC0DM93UDmsRsIUbB+N11NnVi2J7iuO+G29nApNN3A/e9kxeT4RF2dZ/rU0t0B/g2oLVffx8lJqDp7kgEwQXxV1F/kD9o9P0rUlUFvbhGRUhH5hvvPgyVwALxY1IfF87hWAgVACwWh2Q2EyLoH3YunNsdo8VRFbaNZwqmsOnDJJyIKr4fHrYemG9iQH6APcNFG9X08rgeqqqoYABOE1QD4eRHZISIvtnpusAQOgIPdx2nz8BsALRSEZjcQIuu+NWQVNN1A/pnYlU96aKz6AlqZUxKzMRB1VUG3gtw2VX0fz3+SATCBWL0FfIWov3hHq4er1XMP+DiO9SuAFgpCsxsIkTUNzS0F1CtqG2M2jteX7oemGxiygh1BiKLJ6XThxgGqD/CZQKWYlv9VfR9nDmUATDDZIjKx1Z8/JyInxfsikM+JSI92j8kictj9v7sFeczAcwAtFIRmNxAia05V1EHTDdw8MDWmP5qW7TkJTTfwiwkbYjYGoq6o9RSMxuYArSBn/FR9F+d8wgCYYJ4UVf/vORG5TUSmiSoDc4379REiMtfP+wdLJBaBAJYKQnu6gcTydhZRZ+HpxPH94ZkxHUdJpQqiN/Q3cKGeP96IoqWgVPUBviM5QB9gpxN466vqu7g0lwEwAb0iIsdF1QPMFpF7Wr32gYis8/PewRKpAGihIDS7gRAFL/PQGWi6gV9O3BjroeC+kWug6QbW5QWYiE5EYZN9VM2d/0mgVfjlR1umYzmaGADJtuACoIWC0OwGQhS8j7NVC6g/zA6u33YkvbZQFXJ/J/1wrIdC1GWk7S+Bphv4zeQA1TNyDfU9POVeAGAAJNuCC4AWCkKzGwhR8Cy1gIowTxh9YuqWWA+FqMv4cOsxaLqBP80J0Ad43Sj1HbzkzwAYAMm+4AIgEHRBaE83kOTl7AZCFMgby3Li5qpb4Vk1F+mW19PQ0OyI9XCIuoTxGepHYP8l+/1vuPBZ9R28aTwABkCyL/gAGGRB6EU7TkDTDfSOgzlNRPHuxQ93QtMNfLC5KNZDgcvlwl0pq6HpBnYUlcd6OERdwpvB/gic+F31HZyfAYABkOwLPgAGWRC6tKoemm7g+v4GzrGrAJFfv5m8GZpuIHV/fBRg/stcFUjfyyqI9VCIuoSX5u+CphuYtclPH+Cm+pZpWFXq3woGQLIr+ABooSB0r/EbgutrSNTF9Ry1FppuYHucXHF7393P+/lZ2bEeClGX8NS0IHqBl+xV379va6o2LxgAyb7gA2CbgtD+vxxGpOVC0w28umCPhdOAqOu5/Y2V0HQDRWU1sR4KAGB/cSU03UCPN9PhcLKbD1Gk/WxsEKXT9sxX372zfm4+xQBIdgUfAIGgC0JvKTwHTTfwnaGr4eSXCJFXNQ3NZgeAmobmWA8HANDscOKbb6YH15eUiGzzzLs9VOLnezh9oPruTf2X+RQDINllLQAGWRC6sbnlS2R/Mb9EiLzx9M7uPmhlrIfSxjMzs6HpBmb7m5NERLY5nS7c0F/9CCz11wd47q/Vd+/O2eZTDIBkl7UAaKEg9J/m7ICmG5i4Jj+4fRN1MTuKVAeAH41cG+uhtDFxjSpL8dK8XbEeClFCK69p6QPc5PDTB/idb7inX7UUjGcAJLusBUALBaHnbTsWXHVzoi7K0wHg8Tg7R7YdUVM4vjssAy4Xp3AQRUr+mQvQdAN3Dl7le6Oac+o7NzkJaLhgPs0ASHZZC4BA0AWhT5TXms3lK2vZXJ6ovblbiqDpBv4yd2esh9JGfZMDtwxMi6vFKUSJaKv7x9b9o7N8b3R0vfrOHX9nm6cZAMku6wEwyILQAPDA6Ky4qnFGFE/GrDoMTTcwaGlOrIfSgac+4cIdJ2I9FKKEZexTdwH6TPFzF2DrFPWd+9Hv2jzNAEh2WQ+AQRaEBoChnx2Ephv49+LY9zklijf9l+yDpht4NzP+5sm+vVKVcvrnor2xHgpRwgrqLsCyl9V37pqUNk8zAJJd1gOghYLQ6/POQtMN3PNWJucSEbXzxw+2Q9MNzN92PNZD6WBtbik03UDPUfG1QIUokYxdnQdNNzDgUz99gKffr75zc5a0eZoBkOyyHgAtFISub3Lg1kFqLlHuaQvHIOoCek/cCE03sPrgmVgPpYPKuiZcH0x5CiIK2aClqg/wmFU++gA7ncCwr6jv27N5bV5iACS7rAdAoKUg9OaJATd9bpaqKTZ1XaG1YxAluB+OWANNN7DnREWsh+LVI+6Wjp/tOxXroRAlpH7zdvqvuVl+xH3H7SrA0bZYPAMg2RVaAAyyIDQAzN6keov+bvpWa8cgSmAul8tcaXuyoi7Ww/EqefkBaLqBN5fF3yIVokTw26lboOkGVuz18SPr0Ar1XTvlvg4vMQCSXaEFQAsFoY+WqW4HNw9MjZt2V0SxVlnbZBaAbWh2xHo4XnlWKPYavyHWQyFKSD8do/oAb/bVBzjrbfVd++lfOrzEAEh2hRYALRSEdrlc+NHItXE714koFgpKgygAG2OlF+qh6Qau72+gso61PInC7X+Gqj7Ah09f8L7Bwmfc060mdHiJAZDsCi0AAkEXhAZaJrq+vtTPSieiLmRzYRk03cAD/grAxoGeo9SPt7W5pbEeClFCcThd5kKrsxd8VNSYcJf6ni3I7PASAyDZFXoAtFAQOuPgGWi6gXvfXsNyMEQAlu05CU038OS0LbEeil//XLQXmm7g7ZW5sR4KUUIpq24wr7A3e+sD3FQHDL5Cfc9eON3hZQZAsiv0AGihIHRNQ7M54f3I2WrrxyJKMO9vVIujXvlod6yH4tfCHSfY05soAg6fVtNAvj3ExzSQU7vVd+zIG1T5tXYYAMmu0AOghYLQAPD0jK3QdAMzN/pY7k7UhYxIU502hqw4GOuh+FXkXsR1y8A01DfF52IVos7IMw3kp2PWed9g9zz1HTv7F15fZgAku0IPgBYKQgPAtPWF0HQDz84MvC1Rovu/herW6uSs+K6P6XK58N1hGdB0A9uOnIv1cIgSxoq9p6DpBp6Y6mMaSPpA9f2a9m+vLzMAkl2hB0DAUkFoz+Xub7zOKwlEz8xUBdIX7yyO9VACemn+Lmi6gQlx2LOYqLP6YLPqA9xvno8+wHN6q+/XnR94fZkBkOyyFwDNgtDPBNzU5XLh+8MzoekG1uWdDe14RAmil7vLRtbh+F9d6/mi6vv+tlgPhShhjFl12H91jFE3q+/XYu8BkQGQ7LIXAC0UhAYA/ZN9nWLeE1Gk3ZWibqseOFUZ66EEdPBUFTTdwO1vrPS+WpGILBv46X5ouoGxq/M6vlh9Vn23Jn9R1d31ggGQ7LIXAC0UhAaAtP2qs8D9cV77jCiSHE4XbnDX/yq9UB/r4QTkcLrQIzkdmm5gf3H8B1aizuAvc1Uf4Dlbijq+eCRLfa+O/5bP9zMAkl32AiBgqSB0ZV0TbhyQCk03cKK8NvRjEnViZy+o+l839DfgcHaOupjPz1JzFt/nKn6isHhiiuoDbOwr6fjilvfU9+rHT/t8PwMg2WU/AFooCA0AfaZshqYb+HDrsdCPSdSJeW6p3pWSEeuhBO29rAJouoG/zPUxYZ2ILLl/dBY03cCWQi+r65e9pL5X177l8/0MgGSX/QBooSA0AExaq75I/nfOjtCPSdSJrcs7C0038PC49bEeStB2FJVD0w18Z+hqdvMhCoNvDVkFTTeQf8ZLH+BpP3HfWVvq8/0MgGSX/QBosSB0zslKc0J5YzMnlFPXs3hncadbVdvQ7MAtr6tuPoXs5kNkS7PDCU1X84DPVbf73nQ6gJRr1Pdqme/SSwyAZJf9AGixILTT6cJdKauh6QY2F5aFflyiTmpyliqK/trCPbEeiiVPTFVzlj7OPh7roRB1aqUX6n3PA/ZcVEm5WoVBHxgAyS77ARCwVBAaAF5bsAeabmB42iF7xyXqhIZ+drBTfv5Hu+uWvbagcwVXoniTe7rKnFLRwcHl6vt06o/97oMBkOwKTwC0UBAaAJbtOdnp5kARhctfP9oNTTcwY8ORWA/FkvXuuYv3vr0m1kMh6tQ2Fag+wD8b66UPcNYI9X26tJ/ffTAAkl3hCYCegtCjuwe1eXlNI65310E7UxX/ddCIwumpaVuh6QaW7QlcOzOeVDc0m/ULSyrrYj0cok5rubsP8JPTvPQBXvD7oO6oMQCSXeEJgBYLQgNA70mboOkGFm4/Ye/YRJ3MT8esU3NgCzrfHNhHJ2zslOGVKJ7M2nQUmm7gpfm7Or747v+o79LCtX73wQBIdoUnAAKWCkIDwJjVeeoEmOflBCBKYHcO9lP+IZDKYmDfQuBwGnB8G3A2T7WNcjSHf6BeDFlx0H//UiIKyDOf9o1lOW1faKxV7d+Sk4Bq/33CGQDJrvAFQIsFoXceOw9NN3BHcjr7i1KX0dDsMMs/VNQ2Wt+B54eWt8fwrwHjegBTfwTM+RWw6Hngs9eAzKHAlknAnvlegmOTpcOvzFHtHB8ay/m7RKHqv0T1AR6f0a7My8md6lweeWPAfTAAkl3hC4AWC0I7nC7zSsjOY+X2j0/UCZyqqIOmG7h5YKr1gsplBeocG/xfwLSewPg7gRFf9x0Ig30M/xow7g4VEgMNobrBXoC1qaq+CQ+PW4++729jHVHqtP48dwc03cDc9h2xds1V5+QHjwbcBwMg2RW+AGixIDQAvDx/FzTdwOhVh+0fn6gT2HuiAppu4AfDM62/eeNYdY7N+VXb550OoOacCogntgN5q4C9HwNbJ6tWUqn/BBb/AZj7mOow4Cs4plwD1FUEHIanhVXGwTPW/xtsGp+RbwbQt1fmRv34ROHwm8mqJWra/nZ9gFf2d99J6x9wHwyAZFf4AqDFgtAAsGjHCWi6gV9O3Gj/+ESdQMbBM9B0A71D+cxPf0CdX9tnhGcwTgdQW66C46TvBb3v/kv2qTqGqdGtY1hZ14QeyelmALy+P4vJU+d0/zvqR9S2I+36AH/wS3Ue7pobcB8MgGRX+AIgYLkgdGlVvfmPeVn7djhECeij7OPQdAN/mL3d2hurTrVcqasqCby9VVvecxef/VHATZfsUq3sfjVpU/jH4ce4jDyzdtq/Fu+Fphu4563MmNyKJrLjDvcPmYLSdm0VR96ozsOTOwPugwGQ7ApvALRYEBoAHhm/AZpuYOlulpWgxPduprqFqX+yz9obs6dbmmNrWc05NX0jOQk45b/Tx4nyWmi6gZsGpKK2MTqrj1tf/TP2laCmoRk/cV9FefHDndbnUxLFSGNzSx/g8zWtfrxUl7p/5H1RrQYOgAGQ7ApvALRYEBoA3l6ZC0038CrbS1EX8MaynNDmvc7prc6tjeMiMzBArRpOTlIr+v1wuVz4/vDMqNYy9JSNenjcejjdvVP3FVfgpgGprCdKncoZ952vGwekmp9lAKruX3KSqgMYBAZAsiu8AbBNQejioN6y9cg5syeis31TbKIE8+KHO6HpBuZsKQr+TXXngSFfUufVucKIjc38Ahr+9YBXIDzt7MZl5EVuPG6VtU3o8Wa610nzk7MKoekGbntjJY6W1UR8LER2HTyl+gDflZLR9oUtk9T5t+D3Qe2HAZDsCm8ABCwXhG5sduKb7n/c9xUHXoFI1Jn5XP3nz96P1Tk16Z7IDQwAnE5VRzA5Cdjzkd9N5249Bk038PSMrZEdE1qK5ra++ufhcLrw5LQt5mIyloaheLch/6z5eW5jaT917q0dHtR+GADJrvAHQE9B6GUvBf2WP81RNZEmZOYH3pioE/vxqLXQdAM7iizUvvz4aXVOrUmJ3MA81o1Sx5rZy+9mh09fgKYb6D5oJZoiWMi9orbR/IG4Mue0121KKuvMmqIsDUPxbtmek9B0A7+b3u7H09Qfq3Pv4LKg9sMASHaFPwAWbXQXq70CKAluovv8bWpl5G8mbw7fOIji0G1vrISmGygK9nZlY62qzxfE4oywqDypzt3kJKDM9w8yZ6tC7ntORO7K/Tvp6upfr/Eb/E4RSdtfYpaG2VJ4zud2RLH2/kbVB/iVj3a3POl0AClXW5rmwQBIdoU/AALAoufUB/n9h1R9wACKz6tVhTf0N1BZa601FVFnUdPQbK7+q2kIcvXsoc/UuTS2R1DnUljM/6065qpBfjf74wfboekGpq8/EpFhnK9pxO3uwJx+wPvVv9b+vVjVJ/z+cJaGofg1Kl0tfExefqDlybL8lmLsTkdQ+2EAJLsiEwArTwLDvhLUXCKPn45ZZ5Z4IEpEx87VmAsWgvbpX9R5lKZHbmDt5RrqmKNuApp9B6lp69UCjP+dsyMiwxjprhDw83c3BFXmpXVpmH7z4qM0TGOzM/iwT12C/sm+jlOeDixV59y0nkHvhwGQ7IpMAARa2laNuhmorwy4+dDPDkLTDfxr8d7wj4UoDuwoKoemG/jxqLXBvcHRBIy4Tp1HRVHsluNoAt65xT0fabnPzXYfPw9NN/CtIavCvoK/vNXVv9UWWs7tPRE/pWF2HjuPu1Iy8N1hGThVURfTsVD8+F/3nPd521r1AV77luW58wyAZFfkAmBzIzDhrqCvXnhWRn3vrYy4+OVOFG6eeWpBz3U9kqXOn5E3BH1bKGwyktWxP/yNz02aHE50H6RCWt6ZC2E9/Ig0dfXv0QkbLf978F5WQcxLw6zYewq3vJ5m3vL//Yxt/HeNAACPvbep46Imz0KvLe8FvR8GQLIrcgEQAArXuBeE/Bdw5oDfTeubHLh1kPoHM/d0hMZDFENzthSZnSuCYvzD8lWBsDlX2NKVwE9Nz99N3wpNN/Dh1mM+t7F86OoGc7FM5qHgr/55tC8NE8lVyu25XC5McHd70XQDfd/fZv67NtdK7UdKWD3dlQC2t64EMP5b6nw7khX0fhgAya7IBkAAWNC3paxEgF/Az8/KhqYbmLIugsVuiWLEU89u0NKcwBs7naqjTnIScNjCnMFwmv0Ldfyst31uMtbdoeNvH+/2uY1Vw1MPmeEt1KtmpypaSsOMjFJpmIZmB15bsMcMfymfHYTD6cKsTUfNkjlBr/6mhOUpal541t0HuLFG/dBKTgKqzwa9HwZAsivyAbDiBDDsy+rDvW+h301nu/+hfGpa5IvLEkWbZ/L3u8HUuyzeqc6Zt74KNNVHfnDe7FvoXoH8TZ+3oDcVlEHTDfxgeGZYDllW3WDeVl6Ta/3qX2upUSwNc76mEU9M2WK2+Gp9RdTpdOGpaVvN2/8OdjzqshqaHeYPBLPihedcH3WzpX0xAJJdkQ+AALD+HfUBf+cWoN73sY6WqVWSNw9MRTVXzlGC8ZRN+Sj7eOCNM5LVObPw2UgPy7emOmDE19U4CrwHvNrGZnPRRfH5wA3sA3nLffWv96RNYZkz96/FeyNeGqbwbLV5W6/Hm+lYn9fxKs6J8lqzoPVU3uHoskoq66DpBm4akNry+d41R51jc3pb2hcDINkVnQDY3KAaXCcnAekD/W7q6ZRgZeUfUWfQe+JGaLqBjGA+254FVPsXR35g/qT+0x1En/G5Se9JalL7p7uD6//ty9kLDeZ8ubWHS23tyyPSpWG2JHyUxgAAIABJREFUFJ4zbzX/cMQav4thFmxXBe9vGZgW9kUz1DnknKyEphu4e1irPsBp/1bn2MoBlvbFAEh2RScAAkB+RsuCkNJDPjd7Y1kONN3AwE/3R35MRFH0g+GZ0HQDewN1zjh7WJ0rQ64MqoRSRJ3e3zIWH/OThhmqhFP/JfbO2RR3Kahfhenqn0eb0jA7wlcaZuGOE7h5oNrvr9/bhLMXGvxu73K58MJsdRX4FxM2RHVxCsWHdXle+gB75tru/tDSvhgAya7oBUCgZan77F/4XBCSeegMNN3AvW+vYdkEShgul8sMCycD1YTzTJn48PHoDC6QaT3VeDZP8Pry6oPqnP3pmHUhH6L0Qr159W+dl1uodk1aG77SME6nyyxSrekGXp6/C/VNwZXpKa2qN68Yjl2dZ2sc1Pl8urvYLAsEQH0Pvn29u9WjtYVUDIBkV3QD4PljLf0Ofdzaqm1sxi0D09qukiLq5CpqG83A0NAcICxM66nOkR2zojG0wHbMUuOZ+F2vP9zO17T8t52r9n8VzJchK9TVv8feC+/VPw+H04XfTlWLNHrbKA1T3+RAv3k7zf/e0asOWy6CvXzvKXOxyP7iGF/hpaiaseEINN3AXz19gC+cdt8Zu0LNubWAATDxvCwix0SkQUSyReR7frZ9XEQyRKRMRC6IyFYRedji8aIbAAFg3Uj1gR99K9DgfR7M72dsg6YbmLnxaPTGRRRBBaUXoOkG7hy8yv+GlcUt9feqwzMPzrb6qpaV/Me9r9D/2dh1HYvbBqm0qh7fcBdN9raAIlzsloY5e6HBnO9488BUfLIztDmPLpcLL83bBU038OCYdUFfPaTO7233lePBK9x1cQsy1Xk14TuW98UAmFieFJFGEXlBRG4XkekiUiEiV/vYfryI/FtE7haRW0RkuIg0icj/WDhm9ANgU31L0Usfzeanr1e/kp6dmR29cRFF0ObCsuBuk26bqs6N9x+KzsCCtfQlNa6l/by+PPDT/dB0A0M/O2h514NXHICmG3h88uaIT/toXRpm65HgS8McPn0BPxyxxmx9t83Ce70pr2nEXSkZ0HQDb6X6nhNNicWzKn3iGncpqM0T1Hm1oK/lfTEAJpZsEZnU6s+fE5FTItLfwj4OisibFraPfgAEgLx098TyL6kJ7+1fPqOulnzj9TT+OqaEsGzPyeBqXHomhPuYbxczx7epcQ37steFKZ7/vl9OtNaz+ExVvdkybWN+WbhG61fr0jBmLTY/sg6XmiVcfvJOVtjay3nmTl7fv11XCEpYHUpBffpiwGLrvjAAJo4viIhDRH7d7vk5IrI8yH18TkROiMgrFo4bmwAIAPOfVB/8D37ZYV6Ry+XC990rJrPCVA6CKJY6zP3xprZcrZJPTgLK42z6g8sFTLzbPTdxZoeXT1XUmfPaaizU8Exerq7+9ZkS+at/HjUNzWbdvpfm7fJ73LlbinBDfzXf77dTt4S9luA/Fqkw+qORay39/0ad06/cUwjSD7inSky5T51Th1ZY3hcDYOL4qqi/yB+0e36UqCuDwfi3iJwX37eMRUQuFvVh8TyulVgFwPKjwNCr1If/wKcdXvZ0TTDnShB1YsPTVIHjISv83CLdPU+dD5N/GL2BWbF5ohrftJ5eX/bcIt2QH9w8vtOVLVf/NhdE5+qfR6DSMA6ny7w1rekG/rFoLxqbw1+2paq+ySwP9PrS2Ja+2lxYhiW7ill9IYJ+NFL98Nh5rBxwNLd8B56zXhycATBx2A2AT4tIrYg8GGC7we7jtHnEJAACwNrh6sM/5jagoe2K35U5aq7O/aOzYjM2ojB6baHqETs5y88/9B89pc6HtcOjNzAraspUPcDkJKBkX4eXX3X3wR2zquO0Dm88NT+fmLolJqGjdWmY1j16axqa8Qd3vT5NN/BeVkFEx7cxv8w8ViQXwfjiaFfWJvMQi/BHyu1vqDaHR8tqgLN5LdMqnNZ/XDAAJg47t4CfEpE6EflFEMeJnyuAgFr2Pu4OdRJkJLd5qaq+CTe6f6GfKLffYooolp6ZmQ1NN7DY18rRxpqWEkmn47gI+sJn1RiNf3R4af421eniyWlbAu6mpLLOLPe0uTC6V/88vJWGKamswyPjN5hzkI19JVEZiycM3/NWJirrAs9LDJfzNY3o+/42M/xpuoE/frAjasfvSuqbWvoAV9U3qTtfyUnA9PtD2h8DYGLJFpGJrf78ORE5Kf4XgfxOROpF5FchHjN2cwA9clNbOg2U5bd5ydNcfW6rxupEnVEvd6jwWeT44DJ1Hoy7w2eR9LjgKVsx/Osd6pYVlFabwSnQ7dJBS3PMeXWxdKqiDnckqwUery7Yg7uHqZW5d6VkYPfx81EbR21jy7zE1xbuicoxc05W4t631W377oNWmldEbxyQijNV9VEZQ1dy0j1P9uaB7j7Aa1LUubTs5ZD2xwCYWJ4UVf/vORG5TUSmiSoDc4379REiMrfV9k+LSLOIvCQiX271+KKFY8Y+ALpcwLwn1Ikw99dtvvw8/yDxFyl1dp6SHwdP+TjXPvnfoHplx5zTCYztoca6d0Gbl1wuF74zdLV7jpPv8HSqouXqn5VSLJFi7CtpcwXsobHrUXw++ncddh4rNxecmIsEIuTT3cVm7cUfjVyLQyXqc9lnymZouoFJawsievyuaH9xpXmVFwDw0e/UebR1ckj7YwBMPK+IyHFR9QCzReSeVq99ICLrWv15nXiZz+feLlixD4AAUH6kZTLsweXm057G2be9sTIiE7CJosHhdJlf7F77xTY3qitqyUnAsdheEQuKp5j7rJ93eOnPc3cEnOvoqRkYsCROFHkWnT07MxsX6qN3C7a9EWm57iuQq0PuquJPk8NprrzWdAPPzcpuUwpn8c5iMxRa7XBC/q09XApNN/DI+A3qifF3qvPo6Hr/b/SBAZDsio8ACABrhqmTYew3gUb169vpdJlXTmI1T4jIrtIL9dB0Azf0N+Dw9qXqua066ibA2QnqXlYWq9ZVyUlAWdsrRZ5yNy/M3u71rcXna82eyNlH46f2ncvlQt6ZC97/fqKoodlhdlX5y9ydYV18Unqh3rzCp+kGxqzO6xDyahub0cNd8zDaK7MT3SfucN33/W1q0WNyknrUhHYVnAGQ7IqfANhY23JrKXOo+bRn9eRwVsunTurAqUpzXplXn72qPvfL/xrdgdkxr48a8+o32zy9r7gCmm7gjuR0r1eQ+i9RV/+enhE/V//iTc7JSrNEzbI9J8Oyz53HzpvzG3u8mY6Mg75X+r6+dH/gmpVk2bT1hdB0A3//eDdwYrs6f965JeT9MQCSXfETAAHg0GfqpBj632ZdJE+HgYfHhXaZnCjW1uWdhaYb6OW59dOa0wm88w31uc9fHf3BherQCvdVy5sBR8stxGaH0yx14ZlX5nGivNYMNux84d+7mflmkD5dGfqCDJfLhblbj5lXXR8csw5Hzlb7fY9n6s0tA9Nwvia8ha+7Mk8t0KGfHQR2zlbnz5xfhbw/BkCyK74CoMsFfPi4OjE+fBxwuVBe04jr3fOn7PxDSBQrnnlVz3jrbX0iW33e37oWaA7/nK+IcTSpW9bJSeqHWyuesiJzthS1eb7/EjXP7vcztkVxoJ1Tk8OJX07caM5LDOVWcH2TA/90dxrRdAP95u0MutvIz99Vq9ZnboyzjjSdmKfry6S1BUDqv2wv+mIAJLviKwAC6srf0P9u88XiaZ+zcHvHiv1E8W5ylrr1838L93Z8cdUg9Vlf/EL0B2bX6jfU2Oc90eZpz9Wrl+fvMp9rffVv5zFe/QtG/pkLZqcUs3dskE5W1OHRCRvNuadT1xVaCpFztxSZK6LZGSQ8XnAXF1+w/bhaQJWcBOyZH/L+GADJrvgLgACQOcS9IKQH0FiLsavzzF+wRJ3NkBUHoekGRqTltn3B5QLe/bb6rOcsic3g7CgrUGMffAVQ2TJXbUvhOWi6ge+9lWGGh38v3tcyAT4e1ZarL+O66NX+C4ZnUc3tb6wMuiD+poIy/I+7HM+3h6zCxnzrizkq65pw6yAVPqNZDzGR9XZfyFh94DTwtqbOnVOh13xkACS74jMANtYAY25XJ8iaYdh1/LyavJycjmYHy8FQ5/LKR7uh6QZmbDjS9oUzB91zXq8CGi7EZnB2zXpE/TesG2U+Vd/kMOecHT9Xi+Pnas2uPrviMUzUlgPvfV/9d0y8W61yjhMOp8ssiP/E1C1+S7O4XC5MXVdolhz6xYQNtuoZehbg/Xtxx7Z/ZJ2n6Pb+3NyWH07tiqlbwQBIdsVnAARaOiMMvQqOsiPmL1oWKKXO5slpW7yv6PTU02t3C7VT2fuxu4NJjzb9TB+fvNlsfeeZh/astzmQsdZwQbXi8pTk8PQmL80N/N4oOX6uFre5F9a872NOXk1DM16at8uc7/ePRXtR32SvpFD20XKzDmt1kHMHyTfP3+GZXYb7x8Z3be2PAZDsit8A6HKpFVLuL8iFO06Y81niqX4YUSA/HbPOey3LKfepz/euObEZWDg01rYUsS5cYz7tKWj81LSt5tW/uLuV2FQPzP6FGvvbGpCfoa4AJicBI65TC3TixLxtx8w2ewWlbVfxHi2rMWsH3jwwFXO3HgvLvD2Xy4X7R2dB0w18bHEOIrVV19jSB7hh3Vj1GVv4rK19MgCSXfEbAAHVG3jIlUByEly5qXh1wR6zlU45yxNQJ3Hn4FXQdAMFpa1u854/1nIbqKaTF9w1/qH+WxY9Zz61JvdMm/Zqz82KnzAFQK1inv/blhXYJ93zi2vLgRk/Vc+nXAPkpcd2nG4ul8tcXd174kZzKkzGwTNm4ea7h2WEfYGNp3Zd70mbwrrfrqb4fK0qrfN6GlxL/uSeNjHS1j4ZAMmu+A6AgCo0m5wEjLsDNdUXzF+kz83KZqsiinsNzS2//Fu33MLWye52ao/EbnDhUrJP/bcMudLsalBZ12SWb9J0A3tOVMR4kK04HWrVdXISkHI1ULSx7euNNcCHv3EH9P+ytVIznEoq69AjWYW9dzPzMca9OE7TDfxm8maUVoW/TFZZdYM5n7N9XUcK3t4TqkD6D4ZnAlPuVZ+tXMPWPhkAya74D4AN/7+9+w5v8rr+AP7t+LW/0ceZzaKJyV5kNUmTkOWMNm1maZrRGZqkSUrarCaVMcZiDzPCxmGKGTA7CGyDbbbBg2VjlsEDY4aNFxg8pe/vj6Nlg8FGy5LO53neByy/enUlS1fnfe+955ySOTnGMHLNYO4+Uu0oYh63tvV6o0p1BIcrzziS6jYblrOngUgb77/GeVLcU7bnM85x0wtfrztvWTi/sFql4ooxjOx7Obkv6dz7NTWQiz5wzgvcOMq37WzF4m3Fza6shhvMjFma49Va6f+YncVwg5nGZbu89hjBLnWP1AF+ZfQaZ5qzcvdyLGoAqNzV8QNAUlJk2M/WS7ZzzpYihhvMvKnnCmYVdrB5RUq52O565m9XU+aspVtR6L/GeVLGFHk+434hQRbJRVuL+eLo9c2Hvv3JaiWTetmCukvInIXn399icdnflrTX4t8sBFarlR/MzHTMB1yY5f0Vy/ZKNvf2SXJ7YUmoirfNYY+Mi5f30oBr3X4vaQCo3BUYAaDV6qw9Ouw2WiuL+PEcWfHWdXAKK0/rfEDVMa3OPeaYt+Wwdaa8lyc+4b+GeVptlcyZM4Z1qMUTzayNdQZzWaa232/jaOf9Fv29Wek7f6iubeDEtQe456hv+u0mi5VdB6d4tDZxqIlbK3MpZ0waIe+jSc+6fUwNAJW7AiMAJOULxp6ra/yjPFl5gk/HpjLcYOZ7pkzNVq86pLnpRbb3qMswqH3xgZuTwDucxR/J81raw98tOdvmic4gbtPY9t9/+1yZD2gvU1lf4/k2dmCjVu93rOpW7TdwhdQB3hD3ibyHlv3L7WNqAKjcFTgBIElWHiKH3WYrov0qcw6V8daoledOsqtUB2Avixa5yJZMt+6kJH42hkki6GBSmGYb3rqGrO1Afcq22c7gL3XgxR9nX5LzKuekZ2XFcIgoqTzjWNRTUBZawa8nfDFfcmEWjHlZ3j9b4tw+pgaAyl2BFQCSUjpnwLWOKw0zNuU78l91qJWGSpGMXpLDcIOZI5L2yg27Fst7d/T9jrlyQcNqJcc8aBtine7v1ojcpc75lgmR7r/mhzKcZbzGPiQnpSHinWnpDDeYOSSh4yTJDhT21+7UENuCxvz1bh9TA0DlrsALAEnJzWXr1K1rY/nRLFml9viQFFad8e/8HKVcfThT3psz0grkhgXvyhdAUrRf2+U19vly30T4uyVk3mpHHlEu7eG5gLt0r7NU5fA7yOO7PXPcDi4h5wjDDWY+NGA1G7QkZ7u8MnYD7zIscF6J9sDVYw0AlbsCMwAkyfRJjg/T6ay5fGKoTFL+cGaWzgdUHYa9JNrK7CNkYz056Gcde6GEu06VOoOuo9n+a0dhmnO4dv5fJfefJ1UVy4pne9WQoi2ePX4H1NBk4YP9pSRn4q6j/m5OQOk6OIXdIm0VQIbf7pFjagCo3BW4ASDpTNHQ70rmpSc6EpaaNhX4u2VKkSSfsi1Uyiwol1JjtpXs/k4n4lXz/yLPc8VX/nn8ku3OQHvW6xJ4e8PpcnLy886qIXsTvPM4vmC1kvtXyWKX87w3B63c3fFyO3ZwVquVt0evZM+oz+W9MrObR46rAaByV2AHgBYLOe/PjrPwBYmpjqS7OYer/N06pRwF4AtP1JDf2VYALv/M383yrjxboDv4erLhjG8fu3QvOfRGefypv5Zaxd5Uf5qc/Yazasi22d59PG8o3ERO+aVzeHLzxFZ3PVh6ylGT/UiVj/+2AaqmrlEuTPSyVZdJ6uWR42oAqNwV2AEgKV8wttqd1lH38vNpMkTxVGwqT9bqfEDlP/aOP9xgZs2ZOjL2FvkCyEu+8J0DmaWJHHm3PNed8b573IpCmZNnDJPKJL5aidzU4EyBYwwjN3wdGAt8juY4g1d7ZRR7wv3jrS/0eDMuzVGOTl3YoXKpA5wR84i8vtvneuS4GgAqdwV+AEhKZYVR95LGMDbGPcOIQZIa5uM5W3U+oPKbgrIahhvMvKt3Alm0WTr/Qdd7b0iyI1kzWJ7v9Jd883gnj5Kj7nNWI7HVJPYZq5Vc1btDVQ1pVUWBJLQ2XuK8cvndp2R1ieQ4tCcpb+V9ai9H13VwitZjb4NtRRUMNyxntfE6eW2P7PTIcTUAVO4KjgCQJMv2y2RsYxgrpr3JW3ouZ7jBzNlbgqTUlgo4GQXljqvRTIySzn/h+/5ulm9UHnIGGBtGksVZ3qugcbqcHGe7uvL1PWT1Ee88TltsGusMAhe+37GC/VOl5Mr/OBfpGMPI+HfIEy411U8edaa5Wd3nnIepbWjiPcZEhhvMXL+/1CdND2TJu4/xEcMMZ7DdWOeR42oAqNwVPAEgSRZsdBTa3jHlY5kP2Gslc0uC5PmpgLIiW9JmvD5+o+MKNXOX+rtZvuM6vGhPEG16Ra4OHlzjmWoadScl5Yx9dWV5vvvHdNeOec7h1JndyLpT/m1P3UkydRA58Drn32LGa2TJtnPvn7vUFqxcKqupzyFmqeS37DF7qxcbHhzmZxziOz0H2HJHPuyx42oAqNwVXAEgKXOObJ3czNFRDDeY+cywNaypa/R3y1SImZFWwHCDmf2nzHfOrQqlEmKnSmU+3Jw3HVfnm219LycnPSNXR3cvb/+wbcMZctqLcqwhnc87b83n9q+WgNcYRo75OZnclyzY4Nsrgo115OYJzkUxxjDym6cl+L4Q+5zGr7uccy5lbkm1IwH/iVOeuaIVrCasOcBBUR/arrh299hxNQBU7gq+AJAk1w2TRSF9LuUX/Ycw3GDmZ/O263xA5VPDk/Yy3GBmykRb+oe5b/u7Sf5jsUjpu4zJkgx7xJ1nB4T2KyTffSJX0SoKW19M0VjvvMI4sFPrV7P8qThTAtNmV0GvlXZvniArlr3RJ1maZKHByC7Oxx3zc3LXkrY/Xm21BH/GMHLJuWs7vzJ2g5bhPI/GJgvTDpzgG3FpXBz9G3kt18V67PgaACp3BWcAaLWSSz8mjWFs6n81X40ay3CDmfMzQqdskz81NlkYn3mIsYl7OGLVPo5O3s9xqXmMW3uAk9cf5PSN+Zy1uZDfphcxPvMQF28r5rIdJVyRfYSJu44yefcxrt1Xyo15Zdx88AQzC8q5raiC2cVVPFh6KmACecPCnQw3mFka+5B0/oGYIsSbKosk0PvuE2dS5ZbbiDslYMyYLAGkxSIBTnx351XVgo3+fiatO10uwdiiv5OxN5/7+S3pQWYvcH/hitUquQjHP+o8/vDbpSxf00WMgBRucs7jzF121q/nbCliuMHMZ4evCZjPpLedrm9kQs5Rfj5/O+/rm+TIArC7ty2Y3rPCY4+lAaByV3AGgKRMOJ/xGmkMY83AG/mYwcTbo1dy37GT/m5ZUNty8ARf+Hqdo+PzxvaXqek8Xl3r76d6Qe9Oz+DjkdOck789UP4pqNWcIPeYZUh40rPOeXSu2+AbyAmP24aQr5DkxYHCYpHqKBtHS9/U76ctnt8lZNyT5Gojmb+ufYsFijaTU19weZ2ul8U37uZBXG10DrGfbF7942RtA++ITnAmOg9RJ07VcX7GIb5nyuBtvVY266vu75vEr+Zn0WJfeFNR4LHH1QBQuSt4A0CSrK0ixz9GGsNY3P8edjHE87kRa3m6XucDetrx6lp++u02R8d3X98kRi/JYe+lOey5OJv/WbCTX8zfwU+/3cYec7byw5lZfM+Uye7T0vnnKVv4h0mb+cbENHYbv5Gvjt3AF0ev5wtfr+NzI9YyYtgaPj4khY8OSnZUe7m/bxITcvy42rMNXhm7gf2i/uHbdCjBpL6GPLhWFo3MeFWGT+0BTp9LyV2L/d1C9zScIQ+kSGLgCV3PDnYHXCOVTNLGS73hc11lO5ZLznnLeZ/+V5GrYsgzFZ5pY2M9OfFxZ1WVFm34Mn4Hww1m/jt+h2ceL0AUnqjhpHUH+cbENN4Y2fwE9YmhKey3PJdbDp5gY5NF/nb2qQoeTA2kAaByV3AHgKTU7Bx2G2kM45Y+T/Bmw1J+GWKdlTc1NFk4ef1B3h0jaSE6R5rZc3E2K2q8M9k97/hJvjh6vaOz/WrBDp7qoAt8Hh2UzPTeD0vnvyXO380JfE0N5OEsqVRxIMXfrfG8k8dkSHzRB+SwW88OCIffLoszdsZLLrnFH7bI5feJ5PLztOO7nVcr0yc1+1VWYQXDDWbeEZ3A6iBOvG+1WpldXMXhSXv5q5Fnj3C8NGY9Ryfv5+4j1WcPh2cvkNdu8vMebZMGgMpdwR8AkuSRHY6rB/OjX2W4YTkXbS32d6sCXtqBE3x+xFpHJ/jquI3cWVzp9cetb7RwSMIedradeT85NJVZhR664uEhVquVj0TNoSXG9gVdpe831Q5WK3lsl+QVnNlNruyda46kMYyc/1fJg+pNmyfYrjBe3eyxrFarow+YtTm4cq42NFm4YX8Zey/N4aODkpsFfDf1XME/TNrM6RvzebjyPCXxTpc7Fyt994lH26cBoHJXaASAJLkvSYaNjGGMjXqfd/ZOYN5xP+fnClBHq2r5z7nO4d4H+q3ivIwin1cF2HLwBLsOTnHUJh2xah8bmjpG9YXK0/U0RH1BGsNoiXva381Rga6hVtK3rOotQ7J9LpWcioezfPP4FosMw9tTybgk9Z68/iDDDWa+PGaDb9riRafqGmneeYSffLuNXWzJru3bnb0T+NGsLC7eVszK0xcY4WhqlKul9qTaxjCPz1fVAFC5K3QCQJLMmOL4MH7SM5IvfL2OtQ1N/m5VwKhvtDBu7QHe1TvBEXRFL8m5cGfoRdW1Dfxs3vZmVyHzy/yfa2//sZNMjX7SlvphmL+bo4KNP8rMVZc48zmmDHDcXF5Tz1ujZPFDzuEq37fLA5osVs5IK2CXmOZB34P9V9GwcCdT9hxr+3dF/vrmczrHPypzWT1MA0DlrtAKAEkyKZo0hrHeeDnfjBzGyEWeqcsY7DbmlfHZ4WscHWO38Rs7VGe/bEeJozzVHdEJnLOlyK+pKbbk5rMuxraKtXSv39qhlEflLHIuwjmU7rj54zlbGW6QE8JAk1tSzVfHbXT0bU/FpnLQit3MLChnU3tGNSqLyPl/ab5ifcs3F5eCpw00AFTuCr0A0GJxfEgrY67ls5HfcOCK3dxWVNG+D3uIKKk8wx6ztzo6x5/3W8X4zEMdsgh8SeUZ/mHSZkdb3zNlsMzHVQrqG5qYnrKYewdIbdrD/e/y6eMr5XUL35cAZ9R9jjJ3G/aXMdxgZhdjIs/UB8aoyun6Rg5asZs39ZTMAnfHJHJGWkH7vwfqT5OpA53zNPtcSi7/3OtpnzQAVO4KvQCQlPQLk58njWEs6n0zHzLMYrjBzHuMifzH7CzOTS9icYWb+bMCXF1jE8el5jnyfN0YaaZx2S5WnenYK/0sFisnrz/oGJJ6sP8qpuw55tXHtFqt3FlcyamzZzHT6EzCWxtzBRPn6+pfFWTOVJIj7pL3+bJ/kpTP3RNDZT5uICywS917nI8PSXGcLH40K4tHq9qZW9RqJXMWOl8Le7qno765CqoBoHJXaAaAJFlTRuuo+0hjGBuNl3ONMYKf9TSwiyHe0Sk8M3wNjct2MXn3sZCqJbxuXymfGeYc7v39xE3MLQms98juI9XN0jX0WpLt8SsTx6trGbf2AP81NI7ro51zfuqNlzNzwvvMz/fyykyl/CV/vTMFja26xdiU/Qw3mPnGxDQ/N651x6tr2WOOc0Sj6+AUrs69iBPEIzvJab9xBn4j725fqT0P0ABQuSt0A0CSPHGAnPhEs5QKjX2uYPqgX/GzXj15t0sweEvUCr71TRrHpeYxu7iqQw6Buqu44jQ/nJnlMgF6NRdtLQ7YMk/QX093AAAUJklEQVS1DU3stzy3WUCfXezevMXahiYu21HCv05N52s9R3GNfaGH7UTi8OyP2FShJQdVCEjqJe/9oTeRp47zaFWtIynygdKOlWHBYrFy1uZCx8reGyPNHGDObf+Jfc0J8rtPHRkl2P9qcs0QGVXyMQ0AlbtCOwC0O76HTB0khehdgsGmvlcyd8RLNA7sw7sMC5qtDnug3yr+c+42xmceav/QQQdT29DEMcn7eXv0SkeOq77f5QZNYtcN+8v4i4GrGW4w8+aeKzguNa9d83ysViuzCisYuSibXYyJfDFyHFdHP+14n1j6XMb6xT3IiuDKg6bUeTXWOSotcc6bpNXKd6dnMNxg5qAVu/3dOoc9R6vZbbxzkccrYze0fwFbU4MkIB98vfM7Ir47Wem/kz0NAJW7NAB0ZbVKaaWUAeSYB5sFg5Z+V7FwfDfGjY/lQzFLz8oE/8uRa9lveS7X7ivt8JOgaxuamFtSzaXbD3N40l4+HZvqeB5vxKVxz9Hgez9Unq7nP2Y7r26+PmETD5Wff57n4cozHJuynxG24fAXIicwIfo5x3vC2udScsk/yPKDPnoWSnUwx3aR/a6Uz0TmNK7KPeZYLFbf6N+cnGfqmzgkYQ9vti3yuKt3AqdvzG//Io8DqeS4Xzi/DyY+ThZu8k6j20EDQOUuDQBbY7XKZN7kfuToB5oFg9b+V7N82lv8bs44vjE22VGRwr7d2msl34hL41cLdnB08n4u2lrMLQdP8HDlGakN6SNn6puYc7iKi7cVc2jCHr4/I5NPx6aeVbsy3GDmwwNWc+n2wwE73NsWVquVC7OKHWXr7o5J5MKs5kPcp+sbuWhrMf84ebPj7/pcZBxX9v6V8+9vvERWQpbl+fHZKNVBbBrjqF3ceHw/Hx4gV9tXZvuvVvfafaWORSnhBjM/mJnJI1XtHKYtzyfn/sHZ9w+9kcycRlo6xgm+BoDKXRoAtoXVKpN+V/eR1ActCrbXz/0Ls1ZOZ3R8Oh9rUTKo5XZzzxV8fEgK3/omjf+O38GRq/YxPvMQ0w6c4KHy0xdVyaKmrpE7iyu5IKuYg1bu5rvTM/jk0NSzAlPX7R5jIl+fsImRi7I5I62AJ4NkuLctDpWf5usTNjleix6zt3LdvlJ+Gb/DkeQ63GDmM5GTuGHIaxLwOYZ93pEpA0opYbHI6ldjGDnpWcauzGG4wcy/Tk2/8H09rPRkHf/lUqXo0UHJTNp1tH0HqTslfb39ymafy8iVBvJMxyo3qQGgcpcGgO1ltZIl28lVMeTX97QIBq+ldcHfeGRzPJdk5HFM8n7+Z8FO/mnyFj4dm8pbolacNzi0T07uOjiFb0xM4+fztnNE0l7Oyyjixrwy5pfVcFtRBednHuLAFbv5zrR0Rym01rb7+ybxjbg0Ri3O5vSN+dyUV8bjJ2uD+kpfWzRZrByXmucYHnLd3h48h7vH/0GGeO1/23l/kuEupdTZqorJQTI/rnJlP4YbzOwcafZOOi2LRUrgZU6V6k4ZU2hJn8KM+GHsZ/yCUVGfsVfUZzRP7c/atEmOfdq0bRxFDr/d+bmf8VqHPeHTAFC5SwNAd1it5OGtUl1kZJfmwWDfK2ToeGY3cvln5MZRtOQsYdm+dG7fV8Cl2w9zXGoeIxft5J+nbOEzw9bw1l4rLxggtrY92H8V3/omjb2X5nBmWgHTDpzweRLkQLSzuJLPjVjLu2MSOXhOIktnv09rn8ucf8e5b5NHdvi7mUp1fDvjHVfMosdNZ7jBzJGr9nnm2E0NMhfP/AU5/I7mfa03tlH3knvMPk3r0l4aACp3aQDoKVYrWZxFJkY1Twza2jb4ejLuSXLenyWAzJhCy77VPFGUy235x7hsRwnHr8lj1OJs/nVqOp8dvoZ3RCfw4QGr+cfJm2lctouzNhcyPb+c5TX+q8Ub8JoaaDmSTct3n5J9L3f+fWa9LlcZlFJtt+BvpDGMp2Lv4R2GhXxsUPLFV1iqO0XmLpX5tq6rb41h5MDr2DTzd9w3+lUm9H6eK6OfY1LM88wf142Wb/8kV+wvdts0hmzo+JkdNABU7tIA0BusVqkLmb+e3DaLTOlPLnxPqo/E3tKGM9BLJIic9htZZbp2KLljHlm0hTx1vEOflXZYFgtZUUDuXUmuG0YueFeKtPe9ovlrP+O1ZjVOlVLtcKbCcYVuvvF1hhvMTN17vO33rykjt86QtDL9fto8E8PQm1k+9wOmJ83lxORdfMole8F7pkyWVPo+F58/aQCo3KUBoD/U15DHd0swsnmiTDCe+7YEJAOuvXCAOPA6csLjcvVwVQyZZZJgs+qwBDqh7lQpeXANuXkCufRjctKz8pq1+np2Imf9jizY6O+WKxX4Dq5xfLbe6dmfH868wJX08nxy01hy6q+bz7s1hrFswB1cOrQ73+03hjcavjtr6ssjA5OZkNPORR5BQgNA5S4NADsaq1UCmEMZZPYCcl2sBDHTX5J5hi06yLO2/ldJzqq5b8twdMZk8kCKXP1qCrJydnUn5XXKmk6u/A9pelmqErT22vS9gpzQVYaU1o8g9yXKlVq9oqqUZyVEksYwlsZcz4d7fsvSk875yJU1ddy7bQP3zDWwdOiDZ31Os3vfy+FR7/KXkRMZblh+1lzn303YxM/nb+c36w6EVPaCljQAVO7SADDQNNaRZfsleNk8gVzxlcxXG/1A8zlsrQVAox+Q/Vd8JVcf9yXJ1ciy/bYtT7YTB5xb+UHbli9bRYFUvagolACqskgy4lcektWAVcVyNbKySO5Xuk9W0JZsJ4szyaLNcsXyQIo8/h6zzPXJXkDu+JbcOlPybaVPItPGy8q8dcOk5FJStAwPfd3lPM/1EnL0/eS3f5Sk3jmLZCVfU+h+WSjlUw215LhHSGMYE6OfZbex6xg1cgJnG99mcUzzk7TGmEu5KfpRxkT9i48ZTHxowGr+fuImfhm/g+NS87h8ZwlzDlcFTWUiT9EAULlLA8Bg0tQoAVpesgRPCT3JOW/JFcEW82mCZht2Gznzt3K1c9ssWZVdX+Pvv4RS6shONvWRk9LqmKubfW5rjVcyfdCvOW/SUE5ZlckV2UeYW1Ld/tq8IUwDQOUuDQBDhcUiV+by18mQ6aresuJtQldySLisshtk334m28BOtu062QZca9uuka3/1bbtKtn6/dS2XSlXG/tfJfcbfAMZe7NMDv+6i1ydG/uwPHbcUzJHb+oLMsw987fk7N9LBv75f5HFGos/JJf2kCLsKw0S3BZsIE+X+/tVVUqdh2X9SEfQVz/wBlbNeZd1OcvIei/kBwwxGgAqd2kAqJRSyjssFnLXEjnxDLY5yH6mAaBylwaASimlVIDRAFC5SwNApZRSKsBoAKjcpQGgUkopFWA0AFTu0gBQKaWUCjAaACp3aQColFJKBRgNAJW7NABUSimlAowGgMpdGgAqpZRSAUYDQOUuDQCVUkqpAKMBoHKXBoBKKaVUgNEAMPh8DKAQQB2AdAC/uMD+EQC2AagHcABA93Y+ngaASimlVIDRADC4vAUJ5P4G4C4AkwBUAriqlf1vBHAawAgAdwL4J4AmAC+04zE1AFRKKaUCjAaAwSUdwDiXn78PoARAZCv7DwWwq8Vt8wAktuMxNQBUSimlAowGgMHjR5Crd79tcfsMAMtauc96AKNa3PY3ANXteFwNAJVSSqkAowFg8LgO8od8rMXtsZArg+eyH0DPFre9aDvO/7Rynx9D3iz2rRM0AFRKKaUCigaAwcNXAWAf2++bbcXFxayurtZNN91000033QJgKy4u1gAwSPhqCLjlFcAuOEdAqJtuuummm266BcTWCSrgpQMY6/Lz9wEcxvkXgeS0uG0uLmIRCOQNFObhbW+AHFPbGlht1dfAO8fsBO/0BaH+ugbacbWtgdXW/QC+BxXw3oLk/3sHktblG0gamKttvx8MYKbL/vY0MLEA7gDQAxeZBsb2r6ftDpBjeuu42tbAOm6ot9VbfUGov66Bdlxtq7ZV+ck/ARRB8gGmA3jE5XcmAGtb7B8BYLtt/4O4yETQ8E4A+HGAHNNbx9W2BtZxQ72t3uoLQv11DbTjalu1rSpEeDMAVEoFDu0LlFIqhPwYsjL4x35uh1LKv7QvUEoppZRSSimllFJKKaWUUiqoEWfnpVRKhR7tC5RSAekxABYAK/zdED8zAVjajv2DqdO/HsA0AEcANEBW2o8GcEUb7x8BeT0u9UbjlM9oXyBM0L5A+wKlQsAUSMWUU5CSe+74ASRBdyAyITQ7/ZsAHAewAcDTAG4A8BsAuyBJVC9vwzEioJ1+MNC+QJigfYH2BSromdC+D3qw+Qmks78dwDwAUS6/i4B8kF8CkA1Jwr0FUh7PrjuAKgCvQhJuNgHo7N0me40JzvdCIYDPWvx+B2QVqF2wdPoJAIpxdn3sayCJ1Cfafv4xpLpOMSSv5gEA70H+3i1LL5m83GZPMyG0+wFA+wJXJmhf4CqU+gIVQkwI7Y7/XQCZtv+/DPkg28vmREA+wLsB/BLAPQCWAygA8F+2fbpDhgk2AegK+fL4X+832ytMCL1O/3IAVgA9W/n9JAAVkPfEfACHAHSDXCmIgFTn+QGA30Fej9sgXxaXeLPRXmBCaPcDgPYFrkzQvqClUOkLVAgxwflB/zWAjZCz2HIAZgA3u+zbGfLG/h2ANQDOANgJmTcTqDYB+NT2/x8CKIN8mAFnp/+Wy/6XQ573m7afu9v2uc+7zfQJE0Kv038E538en9t+/wvbv8+3sl8EAnvYx4TQ7gcA7QtcmaB9QUuh0heoEGKC84P+OqRTvwXA/QC+gwx32OexdIa8sfdAhkJuA7AA0kH80Eft9aTbATQCuMrltnEAZtn+HwF5vje0uN92AEbb/7tDhgCCodi2CaHb6Xdr5ff2Tv9NyJDef7WyXwQCu9M3IXT7AUD7gpZM0L6gpVDpC1QIMaH1oZ8rIW9k+zyXzraf33PZ5y7bbXd4p3leFQtpe5PLZoGc1V+Ctnf6Vd5vqk+Y4Hwv5EM6PFe5CL5O/wrIsE9UK7+3D/u8guDu9E0I3X4A0L6gJRO0L2gpVPoCFUJMcH7QbwXwLeQDfxJADeSN/KLt951tPz/scv/LbLc95f2metQPARwD8AXki811OwDgIzg/yG+63O8yyGRg12GfYOz00yFfinZhkC/DPi63BUOnDwBJAA7j/BO/O0O+HFob9ukKeT3amiqiozEhNPsBQPuCczFB+wJXodQXqBBigvODvhfyAXgOwJ0A7kbzD3Zn28/3u9z/UtttEV5vqWf9FjJcc64JukMhk8EjIM9tF+Q16QJgGSQv1I9s+3ZHcHb6gwEcBfAkZML7EsgKyT4u+wdLp38rZL7XekgAcz1kHlwOmqd+mA6Z+P1bADdC3h/2L/9OkC+FdwD8FLKiNJCYEJr9AKB9wbmYoH1BqPYFKoSYIB/0KyAf4iddfvcEgrfjX47Wk73aJ/l+Yvv3ZUjHXw85G77XZd/uCJ5OfyaAhbb/h0FSYVRDOrp3EJzzfuzCIZ+FY5CVnIcAjEHzs/j/BjASkiC2HkAegL+5/L435IvSisBL/WBCaPYDgPYF56J9Qej2BSqEmCAd//cBnIBMer4FwLMAMhDcHf+FRCC05nIkQia+q9BjgvYD5xMB7QuUUkHG9UzveUieqzpIWoenEdodfwRCo9O/DHJlow7Bcxav2kf7gfOLgPYFSqkgo2d6rYtAaHT6SyATnwciOFJYqPbTfuD8IqB9gVIqSOiZnlJK+wGllAoxeqanlNJ+QCmllFJKKaWUUkoppZRSSimllFJKqY6tJyST/SkApZBcX7e32Od7APpBElfWAkiGZER39QGAtZDSUK2thusFIA1SJihYEqIqFSx81Rd0BjAVQIHtGAcB9IWzYoZSSikfSIRkqL8bwH2QjPdFAP7PZR8DJGB7DZLZfhmkDuh/u+zzGYBI29ZaANgXUjR8BDQAVKqj8VVf8GtIqaxfAbgJwKsAjgMY7skno5RSqn1+iuZF278HOdv/0mWfSyBpId4+x/0jcOF8WN2hAaBSHZ0v+gK7ryCBpFJKKT+5BdJpd7H9fBPOzuoPAOsAjD7H/SOgAaBSwcAXfYHdAABZF9VKpZRSbvs+ADOAjS63dYV04te22DcewPxzHCMCGgAqFeh81RcAEmhWA/j7xTRUKaWU+yYCKATwM5fbNABUKvT4qi/oBOAAgCkX2U6llFJuGgegGMCNLW7XIWClQouv+oLrAOwHMBNyxVEppZQPfQ/S4Zfg7HQO9t8fBfBvl9vCoItAlAo2vuwLOkGCv28B/OCiW6yUUuqiTYAEY08DuMZl+x+XfQwAKiHpGu6B5AdrmfrhGsiVgfchnf6Ttp8vd9nnBtttMZBcY/fbtp94+DkppdrPV31BJwB5kByCnVo8llJKKR9hK1t3l33syV+PQc72kwHc1uI4fdpwHFMr+0R46LkopS6er/qC7ud5LKWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaUCVwQuXL9bKaWUUkoFiNZKrtm3PgB+BKnD+z3/NFEppZRSSnnSNS7bpwCqW9z2E/81TSmllFJKeVt3AFXnuD0CzYeA7fu9DGAfgDMAFgL4XwDvACgEUAlgDIAfuBznxwCGAygBcBpAuu3YSimllFLKT7qj7QFgA4BVAB4A8BSAEwCSAMwHcBckOKwH8JbLcSYD2ATgSQA3A/gSQB2AWz35JJRSSimlVNt1R9sDQEKCOLs4yFU91yHjRNvtAHADgCYA17U4djKAQRffZKWUUkop5Y7uaHsAeLrFPn0B5La4bQaAxbb/v2Q7Rk2LrRFy1VAppTqc/weGjgBZUMkbJgAAAABJRU5ErkJggg==\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecdc341390>"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.loc['2011':'2012', 'L06_347'].resample('M').agg(['mean', 'median']).plot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>plot the monthly mininum and maximum daily average value of the 'LS06_348' column</li>\n",
"</ul>\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"clear_cell": true,
"collapsed": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [],
"source": [
"daily = data['LS06_348'].resample('D').mean() # daily avergaes calculated"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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BoG4m7vi7cgDSgBHijvjfTNM8vcZgL8a9haLM0bi+233DVvdKYPeWhl1NsAcrP8VwNcdyt861HkPpjVnKszI3ePofxqYEgAPw5z0+xsi/geYuQBvB/B7mPnC/r9LP41ci6vi/XWYq8pfwxwEfmp7/VWHOn4AkgD8GMADMCcLTQPjXu6M9zdsyz6AmZfsblvR3I/u46543wwzrVOw7WfHdYn7uCve98Kcv++GmQbmEZhp3AoAfNn1H0vchQMUD4c69okkq2GuHIJhkjhH9omgG2Ba9Y7iyoPBHpgJoDsBpAJ42XUfQwbJVfGeP4j3+SpMwncepoP4DigZcDd3xnvXAHWmuOizyLW5K94eV1mXuI+74n0XgNMw5+8OmAnAN8Ik/yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiInINUzD4xz+JiIiIyCg30JMC7GU+gC/BPLXnCyOziSIiIiLiSo7PB/0vmEfyOS7To/lEREREbmAeMA+O72sKLr8FbK/3DIBcABcAHAbwPwG8AqAY5uHyawD8lcP7fBnACgAVMM8Dt0DPARYREREZUR4YfAJ4EUAggHsAPATgHIAAAF4AvgOTHHYCmO7wPlsBRAH4KYBvAXgX5sHxE135IURERERk8Dww+ASQMEmc3SaYVj3HW8b+tuUA8A0A3QBu6vPewQCWDH+TRURERMQZHhh8AtjWp84CAJl9lu0GcNT289O292jtU7pgWg1FREREZAR4YGh9AB3NB5DSZ9kuAMdtP0+HaQG8A8BtfcrXndhmEREREXGCB65fAni77T1+6uxGioiIiIjreOD6JYAAsA9AEYDnAHwTwI8BzIa5PSwiIiIiI8AD1zcB/GuYvoJFMKOIK2H6CN413A0WERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERN/lvyWUQFRC7u7cAAAAASUVORK5CYII=\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecdc2059b0>"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"daily.resample('M').agg(['min', 'max']).plot() # monthly minimum and maximum values of these daily averages"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>make a bar plot of the mean of the stations in year of 2013 (Remark: create a `fig, ax = plt.subplots()` object and add the plot to the created ax</li>\n",
"</ul>\n",
"\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"clear_cell": true,
"run_control": {
"frozen": false,
"read_only": false
}
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7fecdc1187f0>"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"data['2013'].mean().plot(kind='barh', ax=ax)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-success\">\n",
"<b>EXERCISE</b>:\n",
"\n",
" <ul>\n",
" <li>Calculate the typical yearly pattern with monthly resolution (plot of the typical monthly average over the years)</li>\n",
"</ul>\n",
"\n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('<div/>');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" this.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
" 'ui-helper-clearfix\"/>');\n",
" var titletext = $(\n",
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
" 'text-align: center; padding: 3px;\"/>');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('<div/>');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('<canvas/>');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('<canvas/>');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('<button/>');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('<span/>');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('<span/>');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('<span/>');\n",
"\n",
" var fmt_picker = $('<select/>');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('<span class=\"mpl-message\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('<div/>')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i<ncells; i++) {\n",
" var cell = cells[i];\n",
" if (cell.cell_type === 'code'){\n",
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
" var data = cell.output_area.outputs[j];\n",
" if (data.data) {\n",
" // IPython >= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<img src=\"data:image/png;base64,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\" width=\"639.7499809339648\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x7f844057fd68>"
]
},
"execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.groupby(data.index.month).mean().plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"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.5.2"
},
"nav_menu": {},
"toc": {
"navigate_menu": true,
"number_sections": true,
"sideBar": true,
"threshold": 6,
"toc_cell": false,
"toc_section_display": "block",
"toc_window_display": true
},
"toc_position": {
"height": "500px",
"left": "0px",
"right": "986px",
"top": "106px",
"width": "214px"
}
},
"nbformat": 4,
"nbformat_minor": 1
}