You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1262 lines
93 KiB
Plaintext

6 years ago
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data exploration\n",
"This notebook provides an example how the data has been loaded and accessed for further analysis."
]
},
{
"cell_type": "code",
"execution_count": 144,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:38.686778Z",
"start_time": "2018-11-09T01:48:31.350515Z"
}
},
"outputs": [],
"source": [
"# Enable autoreloading of our modules. \n",
"# Most of the code will be located in the /src/ folder, \n",
"# and then called from the notebook.\n",
"\n",
"%reload_ext autoreload\n",
"%autoreload"
]
},
{
"cell_type": "code",
"execution_count": 145,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:38.721265Z",
"start_time": "2018-11-09T01:48:38.687781Z"
},
"scrolled": true
},
"outputs": [],
"source": [
"from IPython.core.debugger import set_trace\n",
"\n",
"import pandas as pd\n",
"import numpy as np\n",
"import os\n",
"\n",
"import plotly\n",
"import plotly.graph_objs as go\n",
"import plotly.plotly as py\n",
"\n",
"from ipywidgets import widgets\n",
"from IPython.display import display, clear_output, Image"
]
},
{
"cell_type": "code",
"execution_count": 146,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:55.758881Z",
"start_time": "2018-11-09T01:48:38.723271Z"
},
"pixiedust": {
"displayParams": {}
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\z5189959\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\numpy\\lib\\arraysetops.py:518: FutureWarning:\n",
"\n",
"elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n",
"\n"
]
}
],
"source": [
"data_folder = '../data/interim'\n",
"df_waves = pd.read_csv(os.path.join(data_folder, 'waves.csv'), index_col=[0,1])\n",
"df_tides = pd.read_csv(os.path.join(data_folder, 'tides.csv'), index_col=[0,1])\n",
"df_profiles = pd.read_csv(os.path.join(data_folder, 'profiles.csv'), index_col=[0,1,2])\n",
"df_sites = pd.read_csv(os.path.join(data_folder, 'sites.csv'),index_col=[0])\n"
]
},
{
"cell_type": "code",
"execution_count": 147,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:56.438469Z",
"start_time": "2018-11-09T01:48:55.759856Z"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "89b213f09e874adaa67419df3a32499a",
"version_major": 2,
"version_minor": 0
},
"text/html": [
"<p>Failed to display Jupyter Widget of type <code>VBox</code>.</p>\n",
"<p>\n",
" If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n",
" that the widgets JavaScript is still loading. If this message persists, it\n",
" likely means that the widgets JavaScript library is either not installed or\n",
" not enabled. See the <a href=\"https://ipywidgets.readthedocs.io/en/stable/user_install.html\">Jupyter\n",
" Widgets Documentation</a> for setup instructions.\n",
"</p>\n",
"<p>\n",
" If you're reading this message in another frontend (for example, a static\n",
" rendering on GitHub or <a href=\"https://nbviewer.jupyter.org/\">NBViewer</a>),\n",
" it may mean that your frontend doesn't currently support widgets.\n",
"</p>\n"
],
"text/plain": [
"VBox(children=(HBox(children=(Dropdown(description='site_id: ', index=943, options=('AVOCAn0001', 'AVOCAn0002', 'AVOCAn0003', 'AVOCAn0004', 'AVOCAn0005', 'AVOCAn0006', 'AVOCAn0007', 'AVOCAn0008', 'AVOCAn0009', 'AVOCAs0001', 'AVOCAs0002', 'AVOCAs0003', 'AVOCAs0004', 'AVOCAs0005', 'AVOCAs0006', 'AVOCAs0007', 'AVOCAs0008', 'BILG0001', 'BILG0002', 'BILG0003', 'BILG0004', 'BILG0005', 'BLUEYS0001', 'BLUEYS0002', 'BLUEYS0003', 'BLUEYS0004', 'BLUEYS0005', 'BLUEYS0006', 'BOAT0001', 'BOAT0002', 'BOAT0003', 'BOAT0004', 'BOAT0005', 'BOOM0001', 'BOOM0002', 'BOOM0003', 'BOOM0004', 'BOOM0005', 'BOOM0006', 'BOOM0007', 'BOOM0008', 'BOOM0009', 'BOOM0010', 'BOOM0011', 'BOOM0012', 'BOOM0013', 'BOOM0014', 'CATHIE0001', 'CATHIE0002', 'CATHIE0003', 'CATHIE0004', 'CATHIE0005', 'CATHIE0006', 'CATHIE0007', 'CATHIE0008', 'CATHIE0009', 'CATHIE0010', 'CATHIE0011', 'CATHIE0012', 'CATHIE0013', 'CATHIE0014', 'CATHIE0015', 'CATHIE0016', 'CATHIE0017', 'CATHIE0018', 'CATHIE0019', 'CATHIE0020', 'CATHIE0021', 'CATHIE0022', 'CATHIE0023', 'CATHIE0024', 'CATHIE0025', 'CATHIE0026', 'CATHIE0027', 'CATHIE0028', 'CATHIE0029', 'CRESn0001', 'CRESn0002', 'CRESn0003', 'CRESn0004', 'CRESn0005', 'CRESn0006', 'CRESn0007', 'CRESn0008', 'CRESn0009', 'CRESn0010', 'CRESn0011', 'CRESn0012', 'CRESn0013', 'CRESn0014', 'CRESn0015', 'CRESn0016', 'CRESn0017', 'CRESn0018', 'CRESn0019', 'CRESn0020', 'CRESn0021', 'CRESn0022', 'CRESn0023', 'CRESn0024', 'CRESn0025', 'CRESn0026', 'CRESn0027', 'CRESn0028', 'CRESn0029', 'CRESn0030', 'CRESn0031', 'CRESn0032', 'CRESn0033', 'CRESn0034', 'CRESn0035', 'CRESn0036', 'CRESn0037', 'CRESn0038', 'CRESn0039', 'CRESn0040', 'CRESn0041', 'CRESn0042', 'CRESn0043', 'CRESn0044', 'CRESn0045', 'CRESn0046', 'CRESn0047', 'CRESn0048', 'CRESn0049', 'CRESn0050', 'CRESn0051', 'CRESn0052', 'CRESn0053', 'CRESn0054', 'CRESn0055', 'CRESn0056', 'CRESn0057', 'CRESn0058', 'CRESn0059', 'CRESn0060', 'CRESn0061', 'CRESn0062', 'CRESn0063', 'CRESn0064', 'CRESn0065', 'CRESn0066', 'CRESn0067', 'CRESn0068', 'CRESn0069', 'CRESn0070', 'CRESn0071', 'CRESn0072', 'CRESn0073', 'CRESn0074', 'CRESn0075', 'CRESn0076', 'CRESn0077', 'CRESn0078', 'CRESn0079', 'CRESn0080', 'CRESn0081', 'CRESn0082', 'CRESn0083', 'CRESn0084', 'CRESn0085', 'CRESn0086', 'CRESn0087', 'CRESn0088', 'CRESn0089', 'CRESn0090', 'CRESn0091', 'CRESn0092', 'CRESn0093', 'CRESn0094', 'CRESn0095', 'CRESn0096', 'CRESn0097', 'CRESn0098', 'CRESn0099', 'CRESn0100', 'CRESn0101', 'CRESn0102', 'CRESn0103', 'CRESn0104', 'CRESn0105', 'CRESn0106', 'CRESn0107', 'CRESn0108', 'CRESn0109', 'CRESn0110', 'CRESn0111', 'CRESn0112', 'CRESn0113', 'CRESn0114', 'CRESn0115', 'CRESn0116', 'CRESn0117', 'CRESn0118', 'CRESn0119', 'CRESn0120', 'CRESn0121', 'CRESn0122', 'CRESn0123', 'CRESn0124', 'CRESn0125', 'CRESs0001', 'CRESs0002', 'CRESs0003', 'CRESs0004', 'CRESs0005', 'CRESs0006', 'CRESs0007', 'CRESs0008', 'CRESs0009', 'CRESs0010', 'CRESs0011', 'CRESs0012', 'CRESs0013', 'CRESs0014', 'DEEWHYn0001', 'DEEWHYn0002', 'DEEWHYn0003', 'DEEWHYn0004', 'DEEWHYn0005', 'DEEWHYn0006', 'DEEWHYn0007', 'DEEWHYn0008', 'DEEWHYn0009', 'DEEWHYn0010', 'DEEWHYn0011', 'DEEWHYn0012', 'DEEWHYs0001', 'DEEWHYs0002', 'DEEWHYs0003', 'DEEWHYs0004', 'DEEWHYs0005', 'DEEWHYs0006', 'DEEWHYs0007', 'DEEWHYs0008', 'DIAMONDn0001', 'DIAMONDn0002', 'DIAMONDn0003', 'DIAMONDn0004', 'DIAMONDn0005', 'DIAMONDn0006', 'DIAMONDn0007', 'DIAMONDn0008', 'DIAMONDn0009', 'DIAMONDn0010', 'DIAMONDn0011', 'DIAMONDn0012', 'DIAMONDn0013', 'DIAMONDn0014', 'DIAMONDn0015', 'DIAMONDn0016', 'DIAMONDn0017', 'DIAMONDn0018', 'DIAMONDn0019', 'DIAMONDn0020', 'DIAMONDn0021', 'DIAMONDn0022', 'DIAMONDn0023', 'DIAMONDn0024', 'DIAMONDn0025', 'DIAMONDn0026', 'DIAMONDn0027', 'DIAMONDn0028', 'DIAMONDn0029', 'DIAMONDn0030', 'DIAMONDn0031', 'DIAMONDn0032', 'DIAMONDn0033', 'DIAMONDn0034', 'DIAMONDn0035', 'DIAMONDn0036', 'DIAMONDn0037', 'DIAMONDn0038', 'DIAMONDn0039', 'DIAMONDn0040', 'DIAMONDn0041', 'DIAMONDs0001', 'DIAMONDs0002', 'DIAMONDs0003', 'DIAMONDs0004', 'DIAMONDs0005', 'DIAMONDs0006', 'DIAMONDs0007', 'DUNBn0001', 'DUNBn0002', 'DUNBn0003', 'DUNBn0004', 'DUNBn0005', 'DUNBn0006', 'DUNBn0007', 'DUNBn0008', 'DUNBn
" 'data': [{'name': 'Pre Storm Profile',\n",
" 'type': 'scatter',\n",
" 'uid': '5f83eb47-e017-4192-a508-54a2f91a379c',\n",
" 'x': [0],\n",
" 'y': [0]},\n",
" {'name': 'Post Storm Profile',\n",
" 'type': 'scatter',\n",
" 'uid': '91e7e1e3-4be0-42c5-96f1-6536602059fd',\n",
" 'x': [0],\n",
" 'y': [0]}],\n",
" 'layout': {'legend': {'x': 0, 'y': 1},\n",
" 'margin': {'b': 50, 'l': 20, 'r': 20, 't': 50},\n",
" 'title': 'Bed Profiles',\n",
" 'xaxis': {'autorange': True,\n",
" 'range': [0, 200],\n",
" 'showgrid': True,\n",
" 'showline': True,\n",
" 'title': 'x (m)',\n",
" 'zeroline': True},\n",
" 'yaxis': {'autorange': False,\n",
" 'range': [-1, 20],\n",
" 'showgrid': True,\n",
" 'showline': True,\n",
" 'title': 'z (m)',\n",
" 'zeroline': True}}\n",
"}), FigureWidget({\n",
" 'data': [{'lat': array([-33.46381539, -33.46301835, -33.46221051, ..., -33.4279646 ,\n",
" -33.42732743, -33.42671036]),\n",
" 'lon': array([151.43639576, 151.43690633, 151.43738179, ..., 151.4501613 ,\n",
" 151.45092222, 151.45170635]),\n",
" 'marker': {'size': 10},\n",
" 'mode': 'markers',\n",
" 'text': array(['AVOCAn0001', 'AVOCAn0002', 'AVOCAn0003', ..., 'WAMBE0025', 'WAMBE0026',\n",
" 'WAMBE0027'], dtype='<U12'),\n",
" 'type': 'scattermapbox',\n",
" 'uid': '77f3ed9c-0deb-4ba3-8e85-cffb6b3eaf5c'},\n",
" {'lat': [0],\n",
" 'lon': [0],\n",
" 'marker': {'color': 'rgb(255, 0, 0)', 'opacity': 0.5, 'size': 20},\n",
" 'mode': 'markers',\n",
" 'text': array(['AVOCAn0001', 'AVOCAn0002', 'AVOCAn0003', ..., 'WAMBE0025', 'WAMBE0026',\n",
" 'WAMBE0027'], dtype='<U12'),\n",
" 'type': 'scattermapbox',\n",
" 'uid': '510eb04a-f70a-4364-a348-73c07cb3b8b2'}],\n",
" 'layout': {'autosize': True,\n",
" 'hovermode': 'closest',\n",
" 'mapbox': {'accesstoken': ('pk.eyJ1IjoiY2hyaXNsZWFtYW4iLCJ' ... 'Hp5bCJ9.U2dwFg2c7RFjUNSayERUiw'),\n",
" 'bearing': 0,\n",
" 'center': {'lat': -33.7, 'lon': 151.3},\n",
" 'pitch': 0,\n",
" 'style': 'satellite-streets',\n",
" 'zoom': 12},\n",
" 'margin': {'b': 50, 'l': 20, 'r': 20, 't': 50},\n",
" 'showlegend': False}\n",
"})))))"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"###### Create widget to control which site we're viewing\n",
"textbox = widgets.Dropdown(\n",
" description='site_id: ',\n",
" value='NARRA0001',\n",
" options=df_profiles.index.get_level_values('site_id').unique().sort_values().tolist()\n",
")\n",
"container = widgets.HBox(children=[textbox])\n",
"\n",
"\n",
"# Add panel for pre/post storm profiles\n",
"trace1 = go.Scatter(\n",
" x = [0],\n",
" y = [0],\n",
" name='Pre Storm Profile'\n",
")\n",
"trace2 = go.Scatter(\n",
" x = [0],\n",
" y = [0],\n",
" name='Post Storm Profile'\n",
")\n",
"\n",
"layout = go.Layout(\n",
" title = 'Bed Profiles',\n",
" legend=dict(x=0, y=1),\n",
" margin=dict(t=50,b=50,l=20,r=20),\n",
" xaxis=dict(\n",
" title = 'x (m)',\n",
" autorange=True,\n",
" showgrid=True,\n",
" zeroline=True,\n",
" showline=True,\n",
" range=[0, 200]\n",
" ),\n",
" yaxis=dict(\n",
" title = 'z (m)',\n",
" autorange=False,\n",
" showgrid=True,\n",
" zeroline=True,\n",
" showline=True,\n",
" range=[-1, 20]\n",
" )\n",
")\n",
"\n",
"g1 = go.FigureWidget(data=[trace1, trace2],\n",
" layout=layout)\n",
"\n",
"\n",
"# Add panel for google maps\n",
"mapbox_access_token = 'pk.eyJ1IjoiY2hyaXNsZWFtYW4iLCJhIjoiY2pvNTY1MzZpMDc2OTN2bmw5MGsycHp5bCJ9.U2dwFg2c7RFjUNSayERUiw'\n",
"\n",
"data = [\n",
" go.Scattermapbox(\n",
" lat=df_sites['lat'],\n",
" lon=df_sites['lon'],\n",
" mode='markers',\n",
" marker=dict(\n",
" size=10\n",
" ),\n",
" text=df_sites.index.get_level_values('site_id'),\n",
" ),\n",
" go.Scattermapbox(\n",
" lat=[0],\n",
" lon=[0],\n",
" mode='markers',\n",
" marker=dict(\n",
" size=20,\n",
" color='rgb(255, 0, 0)',\n",
" opacity = 0.5,\n",
" ),\n",
" text=df_sites.index.get_level_values('site_id'),\n",
" ),\n",
"]\n",
"\n",
"layout = go.Layout(\n",
" autosize=True,\n",
" hovermode='closest',\n",
" showlegend=False,\n",
" margin=dict(t=50,b=50,l=20,r=20),\n",
" mapbox=dict(\n",
" accesstoken=mapbox_access_token,\n",
" bearing=0,\n",
" center=dict(\n",
" lat=-33.7,\n",
" lon=151.3\n",
" ),\n",
" pitch=0,\n",
" zoom=12,\n",
" style='satellite-streets'\n",
" ),\n",
")\n",
"\n",
"fig = dict(data=data, layout=layout)\n",
"\n",
"g2 = go.FigureWidget(data=data,\n",
" layout=layout)\n",
"\n",
"def response(change):\n",
" \n",
" site_id = textbox.value\n",
" site_profile = df_profiles.query('site_id == \"{}\"'.format(site_id))\n",
" prestorm_profile = site_profile.query('profile_type == \"prestorm\"')\n",
" poststorm_profile = site_profile.query('profile_type == \"poststorm\"')\n",
"\n",
" poststorm_x = poststorm_profile.index.get_level_values('x').tolist()\n",
" poststorm_z = poststorm_profile.z.tolist()\n",
"\n",
" prestorm_x = prestorm_profile.index.get_level_values('x').tolist()\n",
" prestorm_z = prestorm_profile.z.tolist()\n",
" \n",
" \n",
" with g1.batch_update():\n",
" g1.data[0].x = prestorm_x\n",
" g1.data[0].y = prestorm_z\n",
" g1.data[1].x = poststorm_x\n",
" g1.data[1].y = poststorm_z\n",
"\n",
" # Update \n",
" site_coords = df_sites.query('site_id == \"{}\"'.format(site_id))\n",
" with g2.batch_update():\n",
" g2.layout.mapbox['center'] = {\n",
" 'lat': site_coords['lat'].values[0],\n",
" 'lon': site_coords['lon'].values[0]\n",
" }\n",
" g2.layout.mapbox['zoom'] = 15\n",
" g2.data[1].lat = [site_coords['lat'].values[0]]\n",
" g2.data[1].lon = [site_coords['lon'].values[0]]\n",
" g2.data[1].text = site_coords['lon'].index.get_level_values('site_id').tolist()\n",
" \n",
"textbox.observe(response, names=\"value\")\n",
"widgets.VBox([container,widgets.HBox([g1,g2])])"
]
},
{
"cell_type": "code",
"execution_count": 148,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:59.291083Z",
"start_time": "2018-11-09T01:48:56.439445Z"
}
},
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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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
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 148,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%matplotlib notebook\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111)\n",
"ax.plot(np.random.rand(10), 'o',picker=5)\n",
"text1=ax.text(0,0, \"\", va=\"bottom\", ha=\"left\")\n",
"text2=ax.text(0.5,0.5, \"hello\", va=\"bottom\", ha=\"left\")\n",
"temp = []\n",
"n=1\n",
"\n",
"def onclick(event):\n",
" tx = 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f' % (event.button, event.x, event.y, event.xdata, event.ydata)\n",
" text1.set_text(tx)\n",
" temp.append(tx)\n",
" \n",
"def press(event):\n",
" if event.key == 'x':\n",
" text2.set_text('test')\n",
"\n",
"points = []\n",
"n = 5\n",
"\n",
"def onpick(event):\n",
" if len(points) < n:\n",
" thisline = event.artist\n",
" xdata = thisline.get_xdata()\n",
" ydata = thisline.get_ydata()\n",
" ind = event.ind\n",
" point = tuple(zip(xdata[ind], ydata[ind]))\n",
" points.append(point)\n",
" print('onpick point:', point)\n",
" else:\n",
" print('already have {} points'.format(len(points)))\n",
" return True\n",
"\n",
"fig.canvas.mpl_connect('pick_event', onpick)\n",
"\n",
"fig.canvas.mpl_connect('key_press_event',press)\n",
"fig.canvas.mpl_connect('button_press_event',onclick)\n"
]
},
{
"cell_type": "code",
"execution_count": 149,
"metadata": {
"ExecuteTime": {
"end_time": "2018-11-09T01:48:59.300107Z",
"start_time": "2018-11-09T01:48:59.292086Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 149,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"points"
]
}
],
"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.6.4"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}