Skip to content

Instantly share code, notes, and snippets.

@roadsideseb
Created April 22, 2016 20:52
Show Gist options
  • Save roadsideseb/60363b728e121e10d4bca14429a2748b to your computer and use it in GitHub Desktop.
Save roadsideseb/60363b728e121e10d4bca14429a2748b to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"import math\n",
"\n",
"from collections import OrderedDict\n",
"from decimal import Decimal as D\n",
"from datetime import datetime, timedelta\n",
"from dateutil.relativedelta import relativedelta\n",
"\n",
"\n",
"class CarShareService(object):\n",
" name = None\n",
" \n",
" def calculate_trip_cost(self, start, end, distance):\n",
" raise NotImplemented()\n",
" \n",
" def calendar_days(self, start, end):\n",
" duration = end - start\n",
" hours = ((duration.total_seconds() / 60) / 60)\n",
" days = D(hours // 24)\n",
" \n",
" if not (start.hour == end.hour == 0 and start.minute == end.minute == 0):\n",
" days += 1\n",
" \n",
" return days\n",
" \n",
" def calculate_pvrt(self, start, end):\n",
" duration = end - start\n",
" hours = ((duration.total_seconds() / 60) / 60)\n",
" days = self.calendar_days(start, end)\n",
" pvrt = 0\n",
" \n",
" if hours < 8:\n",
" return D(0)\n",
" \n",
" # PVRT is calculated by calendar day so hourly calculations aren't possible\n",
" # http://modo.coop/blog/pvrt/\n",
" pvrt = days * D('1.5')\n",
" \n",
" #print('PVRT', pvrt)\n",
" return pvrt\n",
" \n",
" def add_tax(self, cost, pvrt=D(0)):\n",
" gst = (cost + pvrt) * D('.05')\n",
" pst = cost * D('.07')\n",
" #print('PST', pst)\n",
" #print('GST', gst)\n",
" return cost + pst + gst + pvrt\n",
" \n",
" \n",
"class ModoCasual(CarShareService):\n",
" name = 'Modo Casual'\n",
" max_day_rate = D('64')\n",
" hourly_rate = D('8')\n",
" rate_map = dict(zip(range(24), [True] * 24))\n",
"\n",
" def calculate_trip_cost(self, start, end, distance):\n",
" duration = end - start\n",
" minutes = duration.total_seconds() / 60\n",
" hours = int(D(minutes // 60))\n",
" \n",
" if minutes % 60 > 0:\n",
" hours += 1\n",
" \n",
" charged_hours = 0\n",
" calendar_days = 1\n",
" cost = 0\n",
" current_date = start.date()\n",
" for h_diff in range(hours):\n",
" point_in_time = start + timedelta(hours=h_diff)\n",
" \n",
" if self.rate_map[point_in_time.hour]:\n",
" charged_hours += 1\n",
" \n",
" if current_date != point_in_time.date():\n",
" if charged_hours >= 8:\n",
" cost += self.max_day_rate\n",
" else:\n",
" cost += charged_hours * self.hourly_rate\n",
" \n",
" calendar_days += 1\n",
" \n",
" charged_hours = 0\n",
" current_date = point_in_time.date()\n",
"\n",
" if charged_hours >= 8:\n",
" cost += self.max_day_rate\n",
" else:\n",
" cost += charged_hours * self.hourly_rate\n",
" \n",
" distance_cost = 0\n",
" if distance > 200:\n",
" distance_cost = (distance - 200) * D('.25')\n",
" \n",
" # FIXME: currently incorrect because the nightly charge cap is not included\n",
" # 8pm - 8am capped at $24\n",
" cost = cost + distance_cost\n",
" \n",
" pvrt = self.calculate_pvrt(start, end)\n",
" return self.add_tax(cost, pvrt)\n",
" \n",
" \n",
"class ModoMemberOwner(CarShareService):\n",
" name = 'Modo Member-Owner'\n",
" max_day_rate = D('40')\n",
" hourly_rate = D('4')\n",
" rate_map = dict(zip(range(24), [False] * 8 + [True] * 15 + [False]))\n",
" \n",
" def calculate_trip_cost(self, start, end, distance):\n",
" duration = end - start\n",
" minutes = duration.total_seconds() / 60\n",
" hours = int(D(minutes // 60))\n",
" \n",
" if minutes % 60 > 0:\n",
" hours += 1\n",
" \n",
" charged_hours = 0\n",
" calendar_days = 1\n",
" cost = 0\n",
" current_date = start.date()\n",
" for h_diff in range(hours):\n",
" point_in_time = start + timedelta(hours=h_diff)\n",
" \n",
" if self.rate_map[point_in_time.hour]:\n",
" charged_hours += 1\n",
" \n",
" if current_date != point_in_time.date():\n",
" if charged_hours >= 8:\n",
" cost += self.max_day_rate\n",
" else:\n",
" cost += charged_hours * self.hourly_rate\n",
" \n",
" calendar_days += 1\n",
" \n",
" charged_hours = 0\n",
" current_date = point_in_time.date()\n",
" \n",
" if charged_hours >= 8:\n",
" cost += self.max_day_rate\n",
" else:\n",
" cost += charged_hours * self.hourly_rate\n",
" \n",
" low_price_distance = 0\n",
" high_price_distance = distance\n",
" \n",
" if distance > 40:\n",
" low_price_distance = distance - 40 \n",
" high_price_distance = 40\n",
" \n",
" distance_cost = low_price_distance * D('.2') + high_price_distance * D('.4')\n",
" \n",
" cost += distance_cost\n",
"\n",
" pvrt = self.calculate_pvrt(start, end)\n",
" return self.add_tax(cost, pvrt)\n",
" \n",
"\n",
"class Evo(CarShareService):\n",
" \n",
" def calculate_trip_cost(self, start, end, distance):\n",
" duration = end - start\n",
" minutes = duration.total_seconds() / 60\n",
" hours = minutes // 60\n",
" \n",
" if minutes % 60 > 0:\n",
" hours += 1\n",
" \n",
" if minutes < 37:\n",
" cost = D(int(minutes)) * D('.41')\n",
" elif hours < 6:\n",
" cost = D(int(hours)) * D('14.99')\n",
" else:\n",
" cost = self.calendar_days(start, end) * D('89.99')\n",
" \n",
" if distance > 200:\n",
" cost += D(int(distance - 200)) * D('.45')\n",
" \n",
" pvrt = self.calculate_pvrt(start, end)\n",
" return self.add_tax(cost, pvrt)\n",
" \n",
" \n",
"class Car2Go(CarShareService):\n",
" \n",
" def calculate_trip_cost(self, start, end, distance):\n",
" duration = end - start\n",
" minutes = duration.total_seconds() / 60\n",
" hours = minutes / 60\n",
" \n",
" cost = D('1') # protection fee (per trip)\n",
" \n",
" if minutes % 60 > 0:\n",
" hours += 1\n",
" \n",
" if minutes < 37:\n",
" cost += D(int(minutes)) * D('.41')\n",
" elif hours < 6:\n",
" cost += D(int(hours)) * D('14.99')\n",
" else:\n",
" cost += self.calendar_days(start, end) * D('89.99')\n",
" \n",
" if distance > 200:\n",
" cost += D(int(distance - 200)) * D('.45')\n",
" \n",
" pvrt = self.calculate_pvrt(start, end)\n",
" return self.add_tax(cost, pvrt) "
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Modo Casual 17.92\n",
"Modo Member-Owner 8.960\n"
]
}
],
"source": [
"start = datetime(2016, 4, 11, 4, 0)\n",
"end = datetime(2016, 4, 11, 6, 0)\n",
"distance = 20\n",
"\n",
"print(ModoCasual().name, ModoCasual().calculate_trip_cost(start, end, distance))\n",
"print(ModoMemberOwner().name, ModoMemberOwner().calculate_trip_cost(start, end, distance))"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from functools import partial"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"car_shares = OrderedDict((\n",
" ('Modo Casual', ModoCasual()),\n",
" ('Modo Member-Owner', ModoMemberOwner()),\n",
" ('Evo', Evo()),\n",
" ('Car2Go', Car2Go()),\n",
"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cost variation for 24h with varying kilometers"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydB3gVxf6GP3ovIipdQVBAxIKKICiKioD1Yi8oFixgpfcmSvXay9W/ShFFUWwIiKIgIFURAqETEiCEkpwQaur/+facTUIMbJJJ2T3nm+fJvSTZ2TPzzmz2dWZ+M8WgJAIiIAIiIAIiIAIiEFIEioVUbVVZERABERABERABERABSADVCURABERABERABEQgxAhIAEOswVVdERABERABERABEZAAqg+IgAiIgAiIgAiIQIgRkACGWIOruiIgAiIgAiIgAiIgAVQfEAEREAEREAEREIEQIyABDLEGV3VFQAREQAREQAREQAKoPiACIiACIiACIiACIUZAAhhiDa7qioAIiIAIiIAIiIAEUH1ABERABERABERABEKMgAQwxBpc1RUBERABERABERABCaD6gAiIgAiIgAiIgAiEGAEJYIg1uKorAiIgAiIgAiIgAhJA9QEREAEREAEREAERCDECEsAQa3BVVwREQAREQAREQAQkgOoDIiACIiACIiACIhBiBCSAIdbgqq4IiIAIiIAIiIAISADVB0RABERABERABEQgxAhIAEOswVVdERABERABERABEZAAqg+IgAiIgAiIgAiIQIgRkACGWIOruiIgAiIgAiIgAiIgAVQfEAEREAEREAEREIEQIyABDLEGV3VFQAREQAREQAREQAKoPiACIiACIiACIiACIUZAAhhiDa7qioAIiIAIiIAIiIAEUH1ABERABERABERABEKMgAQwxBpc1RUBERABERABERABCaD6gAiIgAiIgAiIgAiEGAEJYIg1uKorAiIgAiIgAiIgAhJA9QEREAEREAEREAERCDECEsAQa3BVVwREQAREQAREQAQkgOoDIiACIiACIiACIhBiBCSAIdbgqq4IiIAIiIAIiIAISADVB0RABERABERABEQgxAhIAEOswVVdERABERABERABEZAAqg+IgAiIgAiIgAiIQIgRkACGWIOruiIgAiIgAiIgAiIgAVQfEAEREAEREAEREIEQIyABDLEGV3VFQAREQAREQAREQAKoPiACIiACIiACIiACIUZAAhhiDa7qioAIiIAIiIAIiIAEUH1ABERABERABERABEKMQLAJYBiAepnasASAcgDuAPAdgOYA3gLQAoAPwIcARmRpc37/OIDKAFYB6AFgXYj1C1VXBERABERABEQgiAkEmwBmbapnAQwBUAdAaQCbAHwMYCSA8wDMBjABwBuBjH0A9ATQEcBWAMMAdA1ceySI+4GqJgIiIAIiIAIiEEIEgl0A1wP4FsBAAA8DGAugFoDUQBs/B4CS2Cjw/TYArwF4O/A9RxCjAbwI4LMQ6heqqgiIgAiIgAiIQBATCGYBvA7AXADnAogMiF2TwOie3aStACwCUAVA8cC0MH+2LFOb8x5rAfQO4n6gqomACIiACIiACIQQgWAWwK8AlAVwS6A9PwJQAcB9mdq3cWB9X92AAFIUKYkbM13zBYCDALpn0y/IjyOKCSHUZ1RVERABERABEQgGApUA7AaQFgyVyW0dglUAawLYAeBWAHMCUDi1m98jgLUB7MwtdF0vAiIgAiIgAiLgCgKMEdjlipIUciGCVQCHA3gQQMNMPBnMMS4PawD5XwcvnWQNICOF46OiolC5Mv+pVJQEBg4ciFdeeaUoi6DPDhBQW7irK6g93NMeagt3tMXBgwdRty4n/6wlYJzlC7kUjALIwA2O/r0eiPC1G7ViYGqXUcCjA3I4K7A20I4C5jo/RgF3BsCAkMGBKODzAWQXBWwJYHx8vATQBY/OSy+9hNde40CvUlETUFsUdQuc+PlqD/e0h9rCHW1BAaxShe4nAXRHi+RPKf4DYGpg65fYLLdsBuDdwD6A8QDeAzAqyzUcPXwSANcGrHTYB1ACmD9tli930R/WfMGYLzdRW+QLxny7idoj31Aa30htYYwwX24gAQSCcQQwXzpHDm8iAcwhqMK4bO7cuejQoUNhfJQ+w4GA2sJdXUTt4Z72UFu4oy0kgBJA054oATQlqPwiIAIiIAIiUMgEJIASQNMuJwE0Jaj8IiACIiACIlDIBCSAEkDTLicBNCWo/CLgcQLHjh1DYmKix2uh4otA8BEoXbo0ypbldsD/ThJACaBpj5cAmhJUfhHwMAHKX/369bFnzx4P10JFF4HgJFCjRg1s3749WwmUAEoATXu9BNCUoPKLgIcJ2C8R7QXq4UZU0YOSgL3P38m2aZMASgBNO74E0JSg8ouAhwnYLxHtBerhRlTRg5KA07MpAZQAmnZ8CaApQeUXAQ8TcHrJeLhqKroIeJqA07MpAZQAmnZwCaApQeUXAQ8TcHrJeLhqKroIeJqA07MpAZQAmnZwCaApQeUXAQ8TcHrJeLhqKroIeJqA07MpAZQAmnZwCaApQeUXAQ8TcHrJeLFqkyZNQrdu3ayib9q0CQ0bNjyhGgsXLkS7du2sn/3yyy+47rrrjKu5Y8cOK5r6008/RdeuXY3vZ9/gs88+wyeffILVq1eDbXXWWWehTZs2ePLJJ9PrkG8fls83IotHH30UERERqFevXj7fPfhv5/RsSgAlgKZPgQTQlKDyi4CHCTi9ZLxYNVsAK1eujOeffx4jRow4oRqPPfYYvv76ayQkJGDevHmuFMDU1FTcc889+O677/DII4/g5ptvRrVq1cBo7S+//BI//PAD4uLiUKkSj3x3Z2I7UAC5jYkEMPdt5PRsSgAlgLnvVSfmkACaElR+EfAwAaeXjBerZgsgxWnBggXYunVrejW47yFH0e68805rtM6tAvjyyy9j2LBhlqjefvvt/2oGjlxyJPBkmwS7od0kgGat4PRsSgAlgGY9DJAAmhJUfhHwMAGnl4wXq2aLByXp+uuvB6d8r7rqKqsq06ZNw1NPPYUvvvjCGlXLOgU8depUTJgwARs3bkTFihXRsWNHjBs3DtyQ105Hjx5Fr169rJG448ePo3379ujTpw/atm37ryngnNwvK+OkpCRLUnk/jgA6pZUrV2Ls2LFYunQpDhw4YI22denSBUOGDDlBEOfOnYuRI0di3bp1SElJQe3atfHggw9i8ODB1kfYwswRu8yJ0+XFixfH/PnzrR+zzgMGDLDkmdO75HT55Zdj/PjxOP/889OzSgCdWu7Uv3d6NiWAEkCzHiYBNOWn/CLgaQJOLxkvVs4Wj82bN4PTvZSS999/36oKhe7MM8+0piavvfbaEwTwf//7nyWH9913Hx566CHs3r3bEp3TTjsNf/31F8qXL2/dg7/76quvMHz4cFx22WWWCFEod+7caa3Xs9cA5vR+WRn/+eeflrAy/+OPP+7YBN988w02bNiASy65xJIxCh5Fj+JG4WWi1DVp0gR33323JX08Yox8tm3bhldffdW6husmOWLKn2VO5FSsWLF0AWSf6d27N2644QZLjGNjY/Huu+9ixYoVVjnIl0kC6Nh0p7zA6dmUAEoAzXqYBNCUn/KLgKcJOL1kvFi5zAJIoaGsREdHp4+OcSSsRIkSJwgg19zVqlULzZo1s6TQTosXL7ZG4t5880307NnTCipp2rSpJU0c9bPTM888gw8++CBdAHN6v+z4cmSREjpnzhxLsnKbOLpHIX344Yexb98+S2A5lUz544bflMTsUk4FMGte1pWjghy1HDVqlLXuUgKY21b79/VOz6YEUAJo2ss0BWxKUPlFwMMEnF4ymauWlgYkJBRsZRnTUKyY2WdkFkCORnGUij/jdOUbb7yByMhIa6Qr8whgeHg4LrjgAnz00UfW6GDmxOhejvRx1G/y5MnWSBnXFZ5zzjnpl9mRxXYUcE7vlx8CyGAWrhmk5DFIhFPITBy142jiFVdcYZWX9eN0Net39dVX44wzzjjh43MjgJTU1157zZoqp1Tan8foZI4GSgDN+jBzOz2bEkAJoGkvkwCaElR+EfAwAaeXTOaqHTwIVKlSsJWlS1TmXyWDlFkAGzRogAceeACHDh2yBLBTp07W6F1WAbRH+mbNmmVNE2dOrVq1sqZ/f/31V2s9IKeFeb9y5cqlX0YR4hSrLYA5vV921cztFDDX+3F9HkffLrroIlSoUAHLli2zRix/++03S/aYWGeuFeT/MxiGYsjv7d/nVAAZgXzbbbdZInzXXXehevXq1hpBcuvcuTM+/vhjCaBB/7WzOj2bEkAJoGk3kwCaElR+EfAwAaeXTOaqeXEEkALIKV+KSVpaGsLCwixRO9kI4P/93/+l7yFo1z3zCOCUKVOsYImcjgA63S+7rpObIBBOvXJKl2v+KKZ24lpErh/MLID273h/CiqDRP755x9LjLnFzNNPP21tL8O1jJlT8+bNLcmzg0C4hpDr/Si9dkpOTraEmOsjJYD58wfB6dmUAEoATXuaBNCUoPKLgIcJOL1kvFi1rCOAXKNGMeFauLfffjt9NIwbQNvbwPAaRsVSdiiMdlqyZIm13QrzcZ2fvQbwlVdeQd++fdOvozwxaMMOAsnp/U7Gd/To0Rg6dKg17fyf//znX5fZ28AkJiaiatWq1khe5jWJ11xzDRYtWpStANo3o+xxi5nly5ejRYsWGDNmjCWFe/bswemnn25dRtHlmkcGpdgCyPJQ/hhsYidKH4WTciwBzJ+nxunZlABKAE17mgTQlKDyi4CHCTi9ZLxYtawCmF0dso4A8poPP/zQigK+//77rUhZjoRxixQKFqOA7SlfRvlyDRz36eP2Jz///LP1PdffZY4Czun9sisfBZKBIDNnzrSCOW655RZrlI5lmjFjBr799tv0jaBbt25tRe5yGxaO1FHAOLJHebNHABmgwnWKnAKvW7euFRxC4YuJibGigcuUKWNd37hxY2ud4EsvvZR+DTecPu+889IFkKJL4WWwB7fS4WggBfnIkSPW1LAEMH+eGqdnUwIoATTtaRJAU4LKLwIeJuD0kvFi1XIqgJlHAO16ctsUihS3M+HUKqeOObrGCFc7cf0c9wGcPn06OAJHYeJoIEcKMwsgr8/J/U7FmPkpVH///be17tDeH7BHjx6g+DExqIVCxhE/SipPELnpppssObMFkHsEsh4U2b1791oyyehmrhts1KhRehG+//57S3opg5Q+suBoJwNKuAaSiVPplF+Wy+fzWRL8+uuv44477rACazjtzaRtYMyeHqdnUwIoATTrYdoGxpSf8ouApwk4vWQ8XTkVXgQ8TMDp2ZQASgBNu7dGAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGw1VT0UXA0wScnk0JoATQtINLAE0JKr8IeJiA00vGi1XjGbTdunWzir5p0yY0bNjwhGosXLgQ7dq1s372yy+/gGcCm6YdO3agfv36+PTTT9G1a1fT21nlZz3q1KljnfWbNY0YMQL84hm9SUlJKF68uPFn5vQGNt8tW7agQYMGOc2W79elpKTg/ffftziFh4db92/atCkeffRRPPHEE4XKJN8rB8Dp2ZQASgBN+50E0JSg8ouAhwk4vWS8WDVbUCpXroznn3/eEqXM6bHHHsPXX3+NhIQEzJs3z7UC+NVXX+H48eP4+eefce21155QB0rt/v37rToUhQBSsjZv3lxkAsg633LLLViwYAGeffZZdOjQweLz008/4e2330anTp3wzTffWILs1eT0bEoAJYCmfVsCaEpQ+UXAwwScXjJerJotgI888oglCFu3bk2vxrFjx3DWWWfhzjvvtEbr3CyAv/76Kxo3bmyNAn788cfpdVi0aBGuueYaPPzww9boVzAKYGJiIkqXLn3S7jd48GC8+uqr+PHHH9GxY8cTrqP4sX1Hjx6NAQMGuLoLp6amIi0tDSVKlPhXOZ2eTQmgBNC0c0sATQkqvwh4mIDTS8aLVaMUcYSK07vXX389OOV71VVXWVWZNm0annrqKXzxxRe4+eab/zUFPHXqVEyYMAEbN25ExYoVLbkYN24catSokY7i6NGj6NWrF7788ktrhK59+/bo06cP2rZt+68p4JzcLzvGnAKmAL7yyit45plnsHfvXpQtW9a69Mknn7SmtjmNPXLkyH8J4P/+9z+8++676XW47bbbMH78eJx22mnpH8Up40GDBlk/e/PNN7Fv3z5rlJFSTCHp2bMn5s6dC46i8t99+/ZNz2vz/f333/Haa69ZDMuUKYN7773XYmeXkxnIavjw4eBo5q5du1C7dm08/vjjlpjZo3OUdH42R2Vnz56Nb7/9FsnJyYiNjc22+9kST+6UvewSRwT/+usv7Nmzx/o160lptOuxevVqXHrppRbD+fPnp9+C7cwRYsoj/8OhUaNG+PDDDxEREYH/+7//s+pD+X7vvfdQs2bNEz6a09H8OdumUqVKuP322y3uVapUsa7jlHWpUqUwdOhQixfbaefOnWBZLrjgAglgHv7YeHd8Nw+VLYAsEsACgKpbioBXCASzAHKKki/z888/31orxkShO/PMMy1BpHRkXgPIFzLl8L777sNDDz2E3bt3W6JCeaBMlC9f3roHf0ehodhcdtll1igihZIv808++SR9DWBO73cqAaSIsryUEAoWhZPiMXHiRGttYFYB7N+/vyVlL7zwAm688UZLuih6devWxZIlS9KliwJ49tlno1mzZpZgxsTEWNPlrVu3tqaVOYV65ZVXWvX84IMPrKnVm266ySqqPcJar1493H333dbnLF++3Jpqf+CBB9JHKyk8FKwNGzZY0sPPWrp0qVVmSiXliMkWQMoh24ejd5S8W2+9NdvH6I8//rAkjEJmr/XMeuE777yD5557zipXixYt0LlzZ0vA5syZY11KRkOGDLFkNy4uzhKy9evXW2W0+4Qt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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"\n",
"distances = np.arange(1, 1001)\n",
"\n",
"for label, car_share in car_shares.items():\n",
" casual_partial = partial(car_share.calculate_trip_cost, datetime(2016, 4, 15, 10, 0), datetime(2016, 4, 16, 10, 0))\n",
" values = np.array([casual_partial(d) for d in distances])\n",
" plt.plot(distances, values, '-', label=label)\n",
"\n",
"plt.ylabel('Cost in $')\n",
"plt.xlabel('Driving distance in km')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cost variation with varying number of 24h rental at 100km"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydB3gVxd7G3xQgCR1EkCKCgDRBxQKIIAIiIGIBpQlC6CAqiooigooNRZBeRL2K5Yr1GnrvIGJCCSUQqvSWAoHU7/nvns13CAmbZHJOzpzzzvNwr5Cd2ZnfzLI/ZuY/6wcmEiABEiABEiABEiABnyLg51OtZWNJgARIgARIgARIgARAAeQgIAESIAESIAESIAEfI0AB9LEOZ3NJgARIgARIgARIgALIMUACJEACJEACJEACPkaAAuhjHc7mkgAJkAAJkAAJkAAFkGOABEiABEiABEiABHyMAAXQxzqczSUBEiABEiABEiABCiDHAAmQAAmQAAmQAAn4GAEKoI91OJtLAiRAAiRAAiRAAhRAjgESIAESIAESIAES8DECFEAf63A2lwRIgARIgARIgAQogBwDJEACJEACJEACJOBjBCiAPtbhbC4JkAAJkAAJkAAJUAA5BkiABEiABEiABEjAxwhQAH2sw9lcEiABEiABEiABEqAAcgyQAAmQAAmQAAmQgI8RoAD6WIezuSRAAiRAAiRAAiRAAeQYIAESIAESIAESIAEfI0AB9LEOZ3NJgARIgARIgARIgALIMUACJEACJEACJEACPkaAAuhjHc7mkgAJkAAJkAAJkAAFkGOABEiABEiABEiABHyMAAXQxzqczSUBEiABEiABEiABCiDHAAmQAAmQAAmQAAn4GAEKoI91OJtLAiRAAiRAAiRAAhRAjgESIAESIAESIAES8DECFEAf63A2lwRIgARIgARIgAQogBwDJEACJEACJEACJOBjBCiAPtbhbC4JkAAJkAAJkAAJUAA5BkiABEiABEiABEjAxwhQAH2sw9lcEiABEiABEiABEqAAcgyQAAmQAAmQAAmQgI8RoAD6WIezuSRAAiRAAiRAAiRAAeQYIAESIAESIAESIAEfI0AB9LEOZ3NJgARIgARIgARIgALIMUACJEACJEACJEACPkaAAuhjHc7mkgAJkAAJkAAJkAAFkGOABEiABEiABEiABHyMAAXQxzqczSUBEiABEiABEiABCiDHAAmQAAmQAAmQAAn4GAEKoI91OJtLAiRAAiRAAiRAAroJ4AcA2gGoDCAewCoArwI46tSVqQAuA0gGIO1LA9AIwE6na8YA6AOgGIC/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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"days = np.arange(1, 21)\n",
"start_date = datetime(2016, 4, 15, 10, 0)\n",
"\n",
"for label, car_share in car_shares.items():\n",
" values = np.array([car_share.calculate_trip_cost(start_date, start_date + timedelta(days=int(d)), 100) for d in days])\n",
" plt.plot(days, values, '-', label=label)\n",
"\n",
"\n",
"plt.ylabel('Cost in $')\n",
"plt.xlabel('Full day rental')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cost variation by pick up time\n",
"\n",
"In this scenario we consider a 1-hour rental with a driving distance of 100km and look at how the costs change depending on the time of day we pick up the car. So basically:\n",
"\n",
"* 1-hour rental time\n",
"* 100km driving distance\n",
"* *varying* pick up time at every full hour.\n"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xu2dB5gW1fm3f4BioyiWKEUjVtRo7F3ERmzRWIMasDcs+dti76CiomgACYjG3jUaC/be42dX7AhBojFKiQUp3/UbZzYvL+8yu3t2Z2f2vc8VriA7z8w593mGuTllppUoEIAABCAAAQhAAAJVRaBVVbWWxkIAAhCAAAQgAAEICAEkCSAAAQhAAAIQgECVEUAAq6zDaS4EIAABCEAAAhBAAMkBCEAAAhCAAAQgUGUEEMAq63CaCwEIQAACEIAABBBAcgACEIAABCAAAQhUGQEEsMo6nOZCAAIQgAAEIAABBJAcgAAEIAABCEAAAlVGAAGssg6nuRCAAAQgAAEIQAABJAcgAAEIQAACEIBAlRFAAKusw2kuBCAAAQhAAAIQQADJAQhAAAIQgAAEIFBlBBDAKutwmgsBCEAAAhCAAAQQQHIAAhCAAAQgAAEIVBkBBLDKOpzmQgACEIAABCAAAQSQHIAABCAAAQhAAAJVRgABrLIOp7kQgAAEIAABCEAAASQHIAABCEAAAhCAQJURQACrrMNpLgQgAAEIQAACEEAAyQEIQAACEIAABCBQZQQQwCrrcJoLAQhAAAIQgAAEEEByAAIQgAAEIAABCFQZAQSwyjqc5kIAAhCAAAQgAAEEkByAAAQgAAEIQAACVUYAAayyDqe5EIAABCAAAQhAAAEkByAAAQhAAAIQgECVEUAAq6zDaS4EIAABCEAAAhBAAMkBCEAAAhCAAAQgUGUEEMAq63CaCwEIQAACEIAABBBAcgACEIAABCAAAQhUGQEEsMo6nOZCAAIQgAAEIAABBJAcgAAEIAABCEAAAlVGAAGssg6nuRCAAAQgAAEIQAABJAcgAAEIQAACEIBAlRFAAKusw2kuBCAAAQhAAAIQQADJAQhAAAIQgAAEIFBlBBDAKutwmgsBCEAAAhCAAAQQQHIAAhCAAAQgAAEIVBkBBLDKOpzmQgACEIAABCAAAQSQHIAABCAAAQhAAAJVRgABrLIOp7kQgAAEIAABCEAAASQHIAABCEAAAhCAQJURqHYBvFvSLpK2kfR43PdrSrpS0rqSvpU0UtI5VZYXNBcCEIAABCAAgRZMoJoFsK+kfSRtG/+yALaT9IGk0ZLOlbSypAclXSJpSAvOA5oGAQhAAAIQgEAVEahWAewq6VlJm0n6vGQEsJ+kiyR1ljQrzoNjJB0taaUqyguaCgEIQAACEIBACyZQrQI4RtJtkq6ORS+ZAh4sqYek7Uv6fONYFjtKmtaCc4GmQQACEIAABCBQJQSqUQCPjNf99Y772CN9iQCOkrSIpD4l/b+qpHckdZM0sSwvzM+jhVOrJF9oJgQgAAEIQKClEGgfP9dnt5QG1acd1SaA3ePRvA0lja8ggPUdAewiaUJ9gHMsBCAAAQhAAAK5IeAlYf/MTW0yrEi1CaDX+I2QNEVS0vbFJU2WdKuk5yVdLGmZOq4B7ODY8ePHq0MH/5bSnAROPfVUDRw4sDmrwLVjAvRFvlKB/shPf9AX+eiLKVOmqFs3T+zJy7vsBFVXqk0AF5TUqayXPYK3t6RHJM2QNDbeBTxA0oqS7pfkkcFKu4AjAZw8eTICmINb57jjjtPgwe4qSnMToC+auwfmvD79kZ/+oC/y0RcWwI4d7X4IYD56pHlqMbPkNTCuwRqShsXvAfTI4HBJ59VSNQSwefqs4lX5izU/nUFf5KcvXBP6Iz/9QV/koy8QwP9Ng+ajR4pXCwQwR302ZswY9e6d7O3JUcWqsCr0Rb46nf7IT3/QF/noCwQQAQzNRAQwlCDxEIAABCAAgYwJIIAIYGjKIYChBImHAAQgAAEIZEwAAUQAQ1MOAQwlSDwECk7ghx9+0PTp0wveCqoPgZZHoG3btlpwQe/9nLsggAhgaMYjgKEEiYdAgQlY/pZffnlNmjSpwK2g6hBomQSWXnppffrppxUlEAFEAEOzHgEMJUg8BApMIHmI8C7QAnciVW+RBJL3/NX2mjYEEAEMTXwEMJQg8RAoMIHkIcK7QAvciVS9RRJIuzcRQAQwNPERwFCCxEOgwATSHjIFbhpVh0ChCaTdmwggAhia4AhgKEHiIVBgAmkPmQI3japDoNAE0u5NBBABDE1wBDCUIPEQKDCBtIdMgZtG1SFQaAJp9yYCiACGJjgCGEqQeAgUmEDaQ6aITfvrX/+qAw44IKr6Bx98oBVX9CfR/1eefvppbbnlltEfPProo9pqq62Cmzlu3LhoN/W1116rvn37Bp8vOcGNN96oa665Rq+//rrcV7/4xS+02Wab6bDDDqtpQ6NdrJFPZBYHHnigPvvsMy277LKNfPaWf7q0exMBRABD7wIEMJQg8RAoMIG0h0wRm5YIYIcOHXTsscfqnHPOmaMZBx10kO68805NnTpVjzzySC4FcNasWdp77731t7/9Tfvvv7922mknderUSd6tfdttt+m+++7TN998o/bt2+e2i9wPFkC/xgQBrH83pd2bCCACWP+smjMCAQwlSDwECkwg7SFTxKYlAmhxeuqpp/Txxx/XNMPvPfQo2h577BGN1uVVAM8//3ydddZZkajuuuuuc3WDRy49EljbS4Lz0G8IYFgvpN2bCCACGJZhEgIYSpB4CBSYQNpDpohNS8TDkrTNNtvIU76bbrpp1JSbbrpJhx9+uG655ZZoVK18CviGG27QJZdcorFjx6pdu3bafvvtNWjQIPmFvEn5/vvvdfzxx0cjcT/++KO23nprnXjiidp8883nmgKuy/nKGf/000+RpPp8HgFMK6+++qouuugivfjii/r666+j0bbdd99dZ5xxxhyCOGbMGJ177rl65513NHPmTHXp0kX77befTj/99OgSiTB7xK60eLq8devWevzxx6M/dptPOeWUSJ49vWtO66+/vi6++GKtssoqNaEIYFrPzfvnafcmAogAhmUYAhjKj3gIFJpA2kOmiI1LxOPDDz+Up3stJVdddVXUFAvdUkstFU1N9urVaw4B/Mtf/hLJYZ8+ffSHP/xBEydOjERnscUW02uvvaaFF144Ood/dvvtt+vss8/WeuutF4mQhXLChAnRer1kDWBdz1fO+IUXXoiE1fEHH3xwahfcddddev/997X22mtHMmbBs+hZ3Cy8Lpa6Hj16aK+99oqkz58YM59PPvlEF1xwQXSM1016xNR/VlrMqVWrVjUC6Jw54YQTtO2220Zi/J///EfDhg3TK6+8EtXDfF0QwNSum+cBafcmAogAhmUYAhjKj3gIFJpA2kOmiI0rFUALjWXliy++qBkd80hYmzZt5hBAr7nr3Lmz1lhjjUgKk/Lcc89FI3FXXHGFjjrqqGhTyWqrrRZJk0f9knLkkUdqxIgRNQJY1/NV4uuRRUvoQw89FElWfYtH9yyk/fr101dffRUJrKeSLX9+4bclsVKpqwCWx7qtHhX0qOV5550XrbtEAOvba3Mfn3ZvIoAIYGiWMQUcSpB4CBSYQNpDprRps2dLU6c2bWO9p6FVq7BrlAqgR6M8SuU/83TlkCFD9Pnnn0cjXaUjgO+9955WX311jRo1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Nm3azFXPtHsTAUQAQ5MbAQwlSDwECkwg7SFTxKZZijxC5endbbbZRp7y3XTTTaOm3HTTTTr88MN1yy23aKeddpprCviGG27QJZdcorFjx6pdu3aRXAwaNEhLL710DYrvv/9exx9/vG677bZohG7rrbfWiSeeqM0333yuKeC6nK8SY08BWwAHDhyoI488Ul9++aUWXHDB6NDDDjssmtr2NPa55547lwD+5S9/0bBhw2rasMsuu+jiiy/WYostVnMpTxmfdtpp0Z9dccUV+uqrr6JRRkuxheSoo47SmDFj5FFU//6kk06qiU34Pvnkkxo8eHDEcIEFFtDvf//7iF1STweY1dlnny2PZv7zn/9Uly5ddPDBB0dilozOWdJ9bY/KPvjgg7rnnns0Y8YM/ec//6mYfonEm7tlr1LxiOBrr72mSZMmRT92Oy2NSTtef/11rbPOOhHDxx9/vOYU7mePEFse/Q+HlVZaSSNHjtRnn32mq6++OmqP5Xv48OFaZpll5ri0p6P95+6b9u3ba9ddd424d+zYMTrOU9bzzz+/zjzzzIiX+2nChAlyXVZffXUEsAF/2RR3fLcBjW2CEASwCaBySggUhUBLFkBPUfphvsoqq0RrxVwsdEsttVQkiJaO0jWAfiBbDvv06aM//OEPmjhxYiQqlgfLxMILLxydwz+z0Fhs1ltvvWgU0ULph/k111xTswawrueblwBaRF1fS4gFy8Jp8bj00kujtYHlAnjyySdHUvbHP/5R2223XSRdFr1u3brp+eefr5EuC+Byyy2nNdZYIxLMf/3rX9F0+SabbBJNK3sKdaONNoraOWLEiGhq9Te/+U1U1WSEddlll9Vee+0VXefll1+Optr33XffmtFKC48F6/3334+kx9d68cUXozpbKi1HLokAWg7dPx69s+T99re/rXgbPfPMM5GEWciStZ7lBw4dOlTHHHNMVK91111XO+64YyRgDz30UHSoGZ1xxhmR7H7zzTeRkL377rtRHZOcSATwl7/8ZST3btsXX3yh4447LpJH93tSTjjhhEik/TP/o8O5cOqpp0ZT5B6xLRXAzp07a+WVV47q55xy/RZffHEEsAF/aSKADYBWEoIAhvEjGgKFJtDSBdBy4YezH9xff/21LC0e2fKUW6kAeirOD+ZEAJJOfe6556KHvx/ulhaP7nijgacfPeqXFEuU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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"hours = np.arange(24)\n",
"start_date = datetime(2016, 4, 15, 0, 0)\n",
"rental_time = 1\n",
"\n",
"for label, car_share in car_shares.items():\n",
" values = np.array([car_share.calculate_trip_cost(start_date.replace(hour=h),\n",
" start_date.replace(hour=h) + timedelta(hours=rental_time),\n",
" 100)\n",
" for h in hours])\n",
" plt.plot(hours, values, '-', label=label)\n",
"\n",
"plt.ylabel('Cost in $')\n",
"plt.xlabel('Pick Up Time')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cost variation with a varying rental time during a 24h period"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydCZxO1f/H35aUbKVNoUWptPArCVERUtGuRRtJKZSSSpu1lRaUJKWiRXsqSYqIGFv2fZ+xZMm+M/N/fe/MM/8xzbgzc56Zee7zfM7r5VXMPeee8z7num/fs9wCKImACIiACIiACIiACMQUgQIx1Vo1VgREQAREQAREQAREAAmgBoEIiIAIiIAIiIAIxBgBCWCMdbiaKwIiIAIiIAIiIAISQI0BERABERABERABEYgxAhLAGOtwNVcEREAEREAEREAEJIAaAyIgAiIgAiIgAiIQYwQkgDHW4WquCIiACIiACIiACEgANQZEQAREQAREQAREIMYISABjrMPVXBEQAREQAREQARGQAGoMiIAIiIAIiIAIiECMEZAAxliHq7kiIAIiIAIiIAIiIAHUGBABERABERABERCBGCMgAYyxDldzRUAEREAEREAEREACqDEgAiIgAiIgAiIgAjFGQAIYYx2u5oqACIiACIiACIiABFBjQAREQAREQAREQARijIAEMMY6XM0VAREQAREQAREQAQmgxoAIiIAIiIAIiIAIxBgBCWCMdbiaKwIiIAIiIAIiIAISQI0BERABERABERABEYgxAhLAGOtwNVcEREAEREAEREAEJIAaAyIgAiIgAiIgAiIQYwQkgDHW4WquCIiACIiACIiACEgANQZEQAREQAREQAREIMYISABjrMPVXBEQAREQAREQARGQAGoMiIAIiIAIiIAIiECMEZAAxliHq7kiIAIiIAIiIAIiIAHUGBABERABERABERCBGCMgAYyxDldzRUAEREAEREAEREACqDEgAiIgAiIgAiIgAjFGQAIYYx2u5oqACIiACIiACIiABFBjQAREQAREQAREQARijIAEMMY6XM0VAREQAREQAREQAQmgxoAIiIAIiIAIiIAIxBgBCWCMdbiaKwIiIAIiIAIiIAISQI0BERABERABERABEYgxAhLAGOtwNVcEREAEREAEREAEJIAaAyIgAiIgAiIgAiIQYwQkgDHW4WquCIiACIiACIiACEgANQZEQAREQAREQAREIMYISABjrMPVXBEQAREQAREQARGQAGoMiIAIiIAIiIAIiECMEYg2AbwNaANUAYoDhwGJGfRpVWACMBG4LN3PuwItgZLA1JTy5sTYuFBzRUAEREAEREAEophAtAlgA6A0cCTwfiYCeDgwGVgLHJFOAJ8A2gJXA0uAzsA9wJnAzigeB2qaCIiACIiACIhADBGINgEMdd3lwKhMBPA1oCCwBaiXTgCXAm8Ab6cUVAhYAzwGfBpD40JNFQEREAEREAERiGICsSaANt3bH7gAeCqdANqU72agJhCXps9HALOADlE8DtQ0ERABERABERCBGCIQSwJYDJgONAfGp0zvpo0AlgNWApWABWnGwBBgK/BABuPC+J0EbIuhMaOmioAIiIAIiEA0ECgBrAaSoqEx2W1DLAngu8Bu4NEUSLa+L60A5iQCWBZIyC50XS8CIiACIiACIhARBCz4syoiapLHlYglAVwGlAIOpDC2jSK2S9imfWsAtv4vozWA9q+D9pmsATRp3BIfH0/Jkva/SvlJ4JlnnuGll17Kzyro3ikE1BeRNRTUH5HTH+qLyOiLrVu3Ur58eauMeYHN8sVcijYBtM0dJnW2CWQ4YOFdE769wHFA4TQ9/DhQC7gR+CfluBhb52e7gBulyOBzKbuAz8pkF7AngFu2bJEARsCj0759e954w/bwKOU3AfVFfvfAwfdXf0ROf6gvIqMvTABLlTL3kwBGRo+416IZ8GGa+XwTXJvbrwuMTVd8+ing0I+7AK1S5HGKzzmAEkD3PgtbCfqLNWwonQtSXzgjDGsB6o+w4nQqTH3hhC9smSWAEG0RwLANjiwWJAHMIqi8uGzEiBE0bNgwL26le/gQUF9E1hBRf0ROf6gvIqMvJIASQNeRKAF0Jaj8IiACIiACIpDHBCSAEkDXIScBdCWo/CIgAiIgAiKQxwQkgBJA1yEnAXQlqPwiEHACu3fvZu9e22emJAIiEEkEihQpwhFH2Bdf/5skgBJA17EqAXQlqPwiEGACJn+nnXYaa9fap8WVREAEIolAmTJlWLZsWYYSKAGUALqOVQmgK0HlF4EAEwi9RHQWaIA7UVWPSgKhc/4yO6ZNAigBdB34EkBXgsovAgEmEHqJ6CzQAHeiqh6VBPyeTQmgBNB14EsAXQkqvwgEmIDfSybATVPVRSDQBPyeTQmgBNB1gEsAXQkqvwgEmIDfSybATVPVRSDQBPyeTQmgBNB1gEsAXQkqvwgEmIDfSybATVPVRSDQBPyeTQmgBNB1gEsAXQkqvwgEmIDfSyaITfv444+59957vaovXLiQM84446BmjB07ljp16nh/9ttvv3HFFVc4N3PFihXebuqPPvqIe+65x7m8UAGffvopH374IdOnT8f66oQTTqB27dq0atUqtQ1hu1mYCzIWLVq0YPny5Zx88slhLj36i/N7NiWAEkDXp0AC6EpQ+UUgwAT8XjJBbFpIAEuWLEm7du3o2rXrQc247777+Oabb9i2bRsjR46MSAFMTEzktttuY+jQoTRv3pzGjRtTunRpbLf2l19+yY8//simTZsoUaJExHaR9YMJoB1jIgHMfjf5PZsSQAlg9kfVwTkkgK4ElV8EAkzA7yUTxKaFBNDEacyYMSxZsiS1GXbuoUXRmjRp4kXrIlUAX3jhBTp37uyJ6g033PCfbrDIpUUCMzskOBL6TQLo1gt+z6YEUALoNsJAAuhKUPlFIMAE/F4yQWxaSDxMkurXr49N+daqVctrymeffcaDDz7IkCFDvKha+ingTz75hNdee40FCxZQvHhxrr76anr06IEdyBtKu3bt4vHHH/cicXv27KFevXo88cQTXHrppf+ZAs5KeekZ79u3z5NUK88igH5pypQpvPrqq0ycOJGNGzd60babb76Z559//iBBHDFiBN26dWPOnDkcOHCAsmXLctddd/Hcc895twgJs0Xs0iabLi9YsCCjRo3y/tja/PTTT3vybNO7xqlatWr07NmTs846KzWrBNCv5w79c79nUwIoAXQbYRJAV37KLwKBJuD3kgli40LisWjRImy616Tk3Xff9ZpiQnf88cd7U5N169Y9SADfe+89Tw6bNm3K3XffzerVqz3ROfroo5k2bRpHHnmkV4b97KuvvqJLly5cdNFFngiZUCYkJHjr9UJrALNaXnrGEyZM8ITV8rds2dK3C7799lvmz5/PBRdc4MmYCZ6JnombCa8lk7pKlSpx6623etJnnxgzPkuXLuXll1/2rrF1kxYxtT9Lm4xTgQIFUgXQxkyHDh1o0KCBJ8b//vsv77zzDpMnT/bqYXwtSQB9u+6QF/g9mxJACaDbCJMAuvJTfhEINAG/l0wQG5dWAE1oTFbWrFmTGh2zSFihQoUOEkBbc3fSSSdx3nnneVIYSuPHj/cicX369KFt27beppJzzjnHkyaL+oVS69at6d+/f6oAZrW8jPhaZNEk9JdffvEkK7vJonsmpM2aNWP9+vWewNpUssmfHfhtkphRyqoAps9rbbWooEUtu3fv7q27lABmt9f+e73fsykBlAC6jjJNAbsSVH4RCDABv5dM2qYlJcG2bbnbWNvTUKCA2z3SCqBFoyxKZX9m05W9e/dm5cqVXqQrbQRw3rx5nHvuubz//vtedDBtst29FumzqN+gQYO8SJmtKzz11FNTLwvtLA7tAs5qeeEQQNvMYmsGTfJsk4hNIVuyqJ1FEy+++GKvvtY+m6629l122WUcd9xxB90+OwJokvrGG294U+UmlaH72e5kiwZKAN3GsOX2ezYlgBJA11EmAXQlqPwiEGACfi+ZtE3buhVKlcrdxppLlLS/lRxSWgGsUKECd955J9u3b/cE8JprrvGid+kFMBTpGzZsmDdNnDbVrFnTm/79/fffvfWANi1s5RUtWjT1MhMhm2INCWBWy8uomdmdArb1frY+z6JvVapUoVixYsTFxXkRy9GjR3uyZ8nabGsF7b+2GcbE0H4f+nlWBdB2IF9//fWeCN9yyy0ce+yx3hpB49aoUSMGDhwoAXQYv6Gsfs+mBFAC6DrMJICuBJVfBAJMwO8lk7ZpQYwAmgDalK+JSVJSErNnz/ZELbMI4AcffJB6hmCo7WkjgIMHD/Y2S2Q1AuhXXkZDJzubQGzq1aZ0bc2fiWko2VpEWz+YVgBDP7PyTVBtk8iMGTM8MbYjZh566CHveBlby5g2Va5c2ZO80CYQW0No6/1MekNp//79nhDb+kgJYHj+QvB7NiWAEkDXkSYBdCWo/CIQYAJ+L5kgNi19BNDWqJmY2Fq4t99+OzUaZgdAh46BsWtsV6zJjgljKP3111/ecSuWz9b5hdYAvvTSSzz55JOp15k82aaN0CaQrJaXGd8XX3yRTp06edPON910038uCx0Ds3fvXo466igvkpd2TeLll1/OuHHjMhTAUGEme3bEzKRJk6hatSqvvPKKJ4Vr167lmGOO8S4z0bU1j7YpJSSAVh+TP9tsEkomfSacJscSwPA8NX7PpgRQAug60iSArgSVXwQCTMDvJRPEpqUXwIzakD4CaNcMGDDA2wV8xx13eDtlLRJmR6SYYNku4NCUr+3ytTVwdk6fHX/y66+/er+39XdpdwFntbyM6mcCaRtBvvvuO28zx7XXXutF6axOX3/9Nd9//33qQdCXXHKJt3PXjmGxSJ0JmEX2TN5CEUDboGLrFG0KvHz58t7mEBO+f/75x9sNfPjhh3vXn3322d46wfbt26deYwdOn3nmmakCaKJrwmubPewoHYsGmiDv3LnTmxqWAIbnqfF7NiWAEkDXkSYBdCWo/CIQYAJ+L5kgNi2rApg2Ahhqpx2bYiJlx5nY1KpNHVt0zXa4hpKtn7NzAL/44gssAmfCZNFAixSmFUC7PivlHYqx5Teh+vvvv711h6HzAdu0aYOJnyXb1GJCZhE/k1T7gshVV13lyVlIAO2MQGuHiey6des8mbTdzbZusGLFiqlV+OGHHzzpNRk06TMWFu20DSW2BtKSTaWb/Fq9Nm/e7Elwr169uPHGG72NNTbtbUnHwLg9PX7PpgRQAug2wnQMjCs/5ReBQBPwe8kEunGqvAgEmIDfsykBlAC6Dm9FAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smwE1T1UUg0AT8nk0JoATQdYBLAF0JKr8IBJiA30smiE2zb9Dee++9XtUXLlzIGWeccVAzxo4dS506dbw/++2337BvArumFStWcNppp/HRRx9xzz33uBbn1d/aUa5cOe9bv+lT165dsV/2jd59+/ZRsGBB53tmtYAQ38WLF1OhQoWsZgv7dQcOHODdd9/1OM2bN88r/5xzzqFFixbcf//9ecok7I0D/J5NCaAE0HXcSQBdCSq/CASYgN9LJohNCwlKyZIladeunSdKadN9993HN998w7Zt2xg5cmTECuBXX33Fnj17+PXXX6lbt+5BbTCp3bBhg9eG/BBAk6xFixblmwBam6+99lrGjBnDww8/TMOGDT0+P//8M2+//TbXXHMN3377rSfIQU1+z6YEUALoOrYlgK4ElV8EAkzA7yUTxKaFBLB58+aeICxZsiS1Gbt37+aEE06gSZMmXrQukgXw999/5+yzz/aigAMHDkxtw7hx47j88stp1qyZF/2KRgHcu3cvRYoUyXT4Pffcc7z88sv89NNPXH311QddZ+Jn/fviiy/y9NNPR/QQTkxMJCkpiUKFCv2nnn7PpgRQAug6uCWArgSVXwQCTMDvJRPEppkUWYTKpnfr16+PTfnWqlXLa8pnn33Ggw8+yJAhQ2jcuPF/poA/+eQTXnvtNRYsWEDx4sU9uejRowdlypRJRbFr1y4ef/xxvvzySy9CV69ePZ544gkuvfTS/0wBZ6W8jBjbFLAJ4EsvvUTr1q1Zt24dRxxxhHdpq1atvKltm8bu1q3bfwTwvffe45133kltw/XXX0/Pnj05+uijU29lU8bPPvus92d9+vRh/fr1XpTRpNiEpG3btowYMQKLotr/P/nkk6l5Q3z/+OMP3njjDY/h4Ycfzu233+6xC9XTMhirLl26YNHMVatWUbZsWVq2bOmJWSg6Z5Ju97ao7PDhw/n+++/Zv38///77b4bDLyTxxt1kL6NkEcFp06axdu1a78fWTpPGUDumT5/OhRde6DEcNWpUahHWzxYhNnm0fzhUrFiRAQMGsHz5cj744AOvPSbf/fr148QTTzzo1jYdbX9ufVOiRAluuOEGj3upUqW862zK+rDDDqNTp04eL+unhIQErC7nnnuuBDAHf9kEN76bg8bmQhYJYC5AVZEiEBQC0SyANkVpL/OzzjrLWytmyYTu+OOP9wTRpCPtGkB7IZscNm3alLvvvpvVq1d7omLyYDJx5JFHemXYz0xoTGwuuugiL4poQmkv8w8//DB1DWBWyzuUAJqIWn1NQkywTDhNPF5//XVvbWB6AezYsaMnZY8++ihXXnmlJ10meuXLl+evv/5KlS4TwFNOOYXzzjvPE8x//vnHmy6/5JJLvGllm0KtUaOG187+/ft7U6tXXXWVV9VQhPXkk0/m1ltv9e4zadIkb6r9zjvvTI1WmvCYYM2fP9+THrvXxIkTvTqbVJocWQoJoMmh9Y9F70zyrrvuugwfoz///NOTMBOy0FrP9Bf27duXRx55xKtX1apVadSokSdgv/zyi3epMXr++ec92d20aZMnZHPnzvXqGBoTIQE89dRTPbm3tq1Zs4b27dt78mj9HkodOnTwRNp+Zv/osLHwzDPPeFPkFrFNK4AnnXQSZ555plc/G1NWv2OOOUYCmIO/NCWAOYCWJosE0I2fcotAoAlEuwCaXNjL2V7cGzduxKTFIls25ZZWAG0qzl7MIQEIder48eO9l7+93E1aLLpjGw1s+tGifqFkEmWiFBLArJaX2eAJRQBN8myq1yJ0JmEWdTR5tciWSWBaAbSNKKeffronYiZ9oTRhwgQvAmqRtZBUmQCahJj0hDaQWFTzzTffPGjq1KTJuFi01IQrrQA+9NBDmGiFkkUrO3fu7G3IsDWKgwcPxqbh00Zg7Vq7zuptknTsscemCuBNN93E119/7fs8WRTXJNxELf3ayFDmYcOGeWsELUJokTiLTBoXk73ChQt7PzOxs6l1m0a2cmztoPWpXWNRzJAAmtDZOsxQevXVVz25M2m2+i9dutRjaVHDp556KvW6kKha+SbUoQigybiVbfU4VPJ7NjUFrClg34fF5wIJoCtB5ReBABPwe8mkbZpFS7bt3ZarrS1RpITzwv3QFKVFAC16ZtN69mc2jde7d28vchaKOoWiPSYtNg33/vvve4KVNtnuXov0WTRs0KBBXtTJXuAmEKEU2lkc2gWc1fKyIoA2FWyRMRMmi2jatOynn37qCU1aAbS62/Sw7c410Q0l6zeLMNnOWBMhSyZ9bdq04a233kq9zqKMFgENRc1CPzB5LFasWKoEhfhavUK7qe1aEyETP5v2vuOOO7jrrru8qKP1Q9pk0dTq1avzww8/eGIZ6gtja3nSJpOmULIpY6t3TgTQ7ml9aFJWs2ZNSpcu7ZVjkUD7fffu3bn55pu9jTVWH0shAQxFVEP1MBE3gZw8ebIXCbRpX/vHgY0vk+W03I866ijvZ6+88kqqAD7wwAOpEWkJoNtfJ4oAuvGTALrxU24RCDSB7Ajg1j1bKfVK8nqm3EpbOm6h5OH211LOU1oBtCk4m7rbvn2794K2SIxF79ILYCjSZ5Gj9JsKTBBsqs6Ex9YD2rSwlVe0aNHUStpUbaVKlVLXAGa1vMxamTYCaAJnsmlT0yYjFlGyadf0AmiRNVvnllEyebLjaSxCaclEyq41gQyl9NxCf27RMRMxk1xLoetmz57ttTmUduzY4a19swiZRdKsjibYmdXHom8W3Qz1hU2p2rq+UDLeDRo0SP29Rcxsc0hItrMzBRySYJuitXrVrl3bW2No/yCwdYc2TWvRPNtRbFFMSyEBTH+0j9XLyjCZtClzY2jLATJrp/2DwuQ6FAG08kP3ONQo93s2FQFUBDDnf0sm55QAuhJUfhEIMAG/l0zapgUxAmgCaFO+tgbM6h+SlswigBlJRdoIYGhaM6sRQL/ysiKAdo1Jp62Zsx3MFgk0oUsvgDYFbVPRJlIWeUqfLApo6/7CJYCZRQAtOmmyar8sSmaRU2OfPpnUWiQufV+kFUoT61CyNl9wwQXe+kCL7JosfvfddxkiNEGzqJ9N04Z22NpUsI13+9nQoUOxqXH7ZVFMa8tll12GbWyx/2ZHAEPrDW0ziQlw+mRiaRHZkACaLNqaSL/k92xKACWAfmPI7+cSQD9C+rkIRDEBv5dMEJuePpJl6/FszZht5rB1XpZMOuwA6NAxMHaNbUKoXLmyJ4yhZFOYFi2yfCZXoTWAFm1LuzPW1sPZpo+0awCzUl5WBdCmUW19mcmLTdNaSi+ANgVrG16sHpltjgjdzzUCaOVbPWy3cSjZGjiTG9v0YWsRrR9sunPWrFneGrnMUvq+yMqYszV4Fo21aWSL6qZNtpv4lltu4YUXXvDW6oWSreM0htWqVfPWdVp9TcpsXNiUtPX15s2bvZ262RFA6xuLhFrf2zjLLEkAs9Kz2btGU8DZ45X+agmgGz/lFoFAE4gFAcyogzKKOoXWwIXWr1mkzaZJLZpm0aTQlK9NpdpmDJvGM5mwDQL2+/j4+IN2AWe1vIzql3YKOLMBll4A7Trb/NGrVy9v3ZntlLXNDLbm0aZibQ2g/ZmlcAhg2l3AcXFx3lSoCZCtRbRkR7nYFK4Jkm0wqVKlijeFa2sUf/zxRy8KZ/XLLAJ4qAcr7UHQ1lbboWxRRlufZxE5+71FB9N+IcVE1OpgkUSTfNvcYckE0nYHW0Qx7c7eQ00BW7ts2timgC2ZWNp9bQrZIoi2q9i4W3n2DwdbRykBDP9flRJAN6YSQDd+yi0CgSYQywKYNgIY6kTbGGBTrRbFsnMAberY1rTZ1Gso2RSkCc0XX3zhCY2Jg0UDLVKY9hgYuz4r5WUmgDalaDt7DyWAtnnB6pBWdGwK1mTEhMdkx3adWh3tiJjQJgWbFjW5TfuVlEOtAbQIaWhzROg6+71tKrF62qHNJs7GzuQnlKxutgHCjslZtmyZt5nEooO2+cNk1eqdkwiglZ+TT8HZ1LGt37T1f6HzCq0NJnAWMUx7cLQJoEUu0/dp+jWAobba8gCLiBp34xvibmXaRiSrr3GyKKkdQeOX/J5NTQFH3xTwbUAboApQHLBYdGLKQLkYsBW+1QBbfWx/M7wJfJRuINl3j1qmrO+bmlLenEwGmwTQ7ynUz0Ugign4vWSiuOlqmghENAG/Z1MCGH0CaFueSgN24qjF0dMKoH3v5jj73CGwAbCvmQ+1c0mBH1JGsh1M1dbOO7VNTIBtZ7Ivk9sCjJ0ZjHYJYET/FaDKiUDuEvB7yeTu3VW6CIhAZgT8nk0JYPQJYGgs2EIN+z5NWgHMaJzYFqjlwGMpP1xqh5wDySudwT4wuCbl559KAPWXjQiIQFoCfi8Z0RIBEcgfAn7PpgQwtgXQonfzbf0pMDhlynczUBOISzNkbUvbLKCDBDB/HmTdVQQilYDfSyZS6616iUC0E/B7NiWAsSuAFhm0aV/775Up6wTLASsBO5nz/w9PgiHAVuABCWC0/5Wh9olA9gj4vWSyV5quFgERCBcBv2dTAhibAmgbQGzq1z4kaF/LDq3ts4igIoDhevpUjgjEAAG/l0wMIFATRSAiCfg9mxLA2BNAO959WMomkCbAvnQjN6M1gKuB9kCmawDtm5C2Pd1Sw4YNvV9KIiAC0U/A7yUT/QTUQhGITAIZPZt2fmHooHI7YseO+wHs+4w2yxdzKdrOASyYMq1rm0CGA/ZdGfsa9l7geGAkYEe62Bez//8r2f/f7bbOz3YBN7Jvc6ccG2O7gM/SLuCYezbUYBHwJSAB9EWkC0QgXwj4PZuKAEZfBLAZYF/rDn040QTX/r9uyrEvdqxLaMo3dM2fKcIXGqT2VepWKfI4RecA5suzq5uKQCAI+L1kAtEIVVIEopCA37MpAYw+AczrYaxzAPOauO4nAhFEwO8lE0FVVVVEIKYI+D2bEkAJoOsDIQF0Jaj8IhBgAn4vmQA3TVUXgUAT8Hs2JYASQNcBLgF0Jaj8IhBgAn4vmaA2zb5Xe++992ZY/aOOOsr7FqySCEQyAb9nUwIoAXQdvxJAV4LKLwIBJuD3kglq00wAW7Rowddff03ZsmUPakbhwoW58MILg9o01TtGCPg9mxJACaDroyABdCWo/CIQYAJ+L5mgNi0kgIsWLaJChQpBbYbqHcME/J5NCaAE0PXxkAC6ElR+EQgwAb+XTFCb5ieAU6ZM4eKLL+aHH36gcePGBzWzdevWfPPNN6xevZpChQqxf/9+unTpwqeffur92UknncRdd91F586dsWiikgjkBgG/Z1MCKAF0HXcSQFeCyi8CASbg95IJatNCAjh//vz/RAALFixIgQIFqFSpElWqVGHIEPtaZnLat28fJ554ou8B8N4AACAASURBVCd4vXr18v7sjjvu8KaSn332WWrVqsVff/3FCy+8wK233sonn3wSVESqd4QT8Hs2JYASQNchLAF0Jaj8IhBgAn4vmaA27VCbQCziZ5G/l156iRdffJG1a9dSooSduQ/ff/89N998M5MmTaJq1arMmTOH888/n65du/L888+n4rB8nTp1YsaMGZx33nlBxaR6RzABv2dTAigBdB2+EkBXgsovAgEm4PeSOahpSUmwbVvuttZErID7B55CEUATuvSbQGwXsK0LXLlyJaeddhoDBgzwNoxYMvmbN28ec+fO9X7fr18/2rZtS/q1hCtWrPDyvvXWW9inNJVEINwE/J5NCaAE0HXMSQBdCSq/CASYgN9L5qCmbd0Kpeyzo7mYtmyBkvbXklvyWwMYKr1uXfvIEowePZotW7ZQpkwZb21fx44dvT8PRfq2b99O0aJFUyu1Z88e7/fpI4NutVZuEfh/An7PpgRQAuj6vEgAXQkqvwgEmIDfS+agpgUwAui3C3jgwIE88MADLFu2jOHDh2MbQOz/y5cv7zU9FAFcvHixF/ELJUUAAzzoA1J1v2dTAigBdB3KEkBXgsovAgEm4PeSCWrTshoB3LZtmxf1e+655zwBtF2/Fg0MpdAaQIsEPv3006l/HooMzpw5k3PPPTeomFTvCCbg92xKACWArsNXAuhKUPlFIMAE/F4yQW1aaBPIV199Rbly5f7TjGrVqmG7gS01bdqUP//809sM8v7779O8efODrr/zzjtTdwFfcsklqbuAb7vtNgYPHhxURKp3hBPwezYlgBJA1yEsAXQlqPwiEGACfi+ZoDYtFAHMrP7r16+ndOnS3o9//vlnrr32Wm9N35o1a1J3BIfy2jmA3bp182QvdA7gPffc4+0CtoihkgjkBgG/Z1MCKAF0HXcSQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNNUdREINAG/Z1MCKAF0HeASQFeCyi8CASbg95IJcNO8qk+YMIFevXoxbtw4NmzY4H3n98ILL+Suu+7yfhUsWNCpiYmJibzxxhsMHz6cOXPmsHPnTipWrEibNm249957KVCgwH/Kt2vfffddJk2axMaNGylevDjnnnuu9z3iVq1aUapUKac6KXN0EPB7NiWAEkDXkS4BdCWo/CIQYAJ+L5kAN80Tv8cff5x69erRrFkzTjnlFDZt2sSvv/7Khx9+yOeff+5Jl0vasWMH5cqVo3nz5lxxxRWezP3888+eFHbo0IFXX331oOLbtWvHW2+9xc0330yTJk0oW7YsmzdvZtSoUV6d7rjjDvr27etSJeWNEgJ+z6YEUALoOtQlgK4ElV8EAkzA7yUT1KaNHTuWunXr8sgjj/Dmm2/+pxnLli3D5O28887LcRP37t1L4cKFMYZHHXXUQeXcd999nmCacB5++OHezz766CNatGhB7969efjhh/9zX4sGjh492hNDJRHwezYlgBJA16dEAuhKUPlFIMAE/F4yQW1ao0aNmDx5MgkJCRQpUiTTZti08HPPPeeJl117zDHHcOmll9KzZ09OOumk1HxdunShW7duzJo1y4sqjh8/nvr16/Pdd99lWLZN8do08MqVK70on6VKlSpRtGhRpk2blmWsCxcu5KmnnuKPP/5gz549VKlSBatLw4YNs1yGLgwmAb9nUwIoAXQd2RJAV4LKLwIBJuD3kgli02xdnq31u/HGG/nkk08O2QQTrH79+nH55Zdz7LHHsnr1al5//XXWr1/P/PnzU+Wxa9eu2K/TTz8di+7VqFHDWz942WWXZVj+7bffzsiRI71y7Dor16aKn332Wbp3754l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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"hours = np.arange(24)\n",
"start_date = datetime(2016, 4, 15, 8, 0)\n",
"\n",
"for label, car_share in car_shares.items():\n",
" values = np.array([car_share.calculate_trip_cost(start_date,\n",
" start_date + timedelta(hours=int(h)),\n",
" 100)\n",
" for h in hours])\n",
" plt.plot(hours, values, '-', label=label)\n",
"\n",
"plt.ylabel('Cost in $')\n",
"plt.xlabel('Rental Time (hours)')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cost variation rental < 1h varying by the minute"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\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",
" 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 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);\n",
" canvas.attr('height', height);\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'];\n",
" var y0 = fig.canvas.height - msg['y0'];\n",
" var x1 = msg['x1'];\n",
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\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",
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydB5gV1fmHf3Ski4KCLOyuJVaMsSt2DbGgxhrsvWGJoIbem6jYAhaImthbNBoL9ootf6NB7NIFFBAWUGSB3f/zzd5ZL9e7zN177r175847z8MTw843c8473+y8nDnnm3pigwAEIAABCEAAAhCIFIF6keotnYUABCAAAQhAAAIQEAJIEkAAAhCAAAQgAIGIEUAAI3bB6S4EIAABCEAAAhBAAMkBCEAAAhCAAAQgEDECCGDELjjdhQAEIAABCEAAAgggOQABCEAAAhCAAAQiRgABjNgFp7sQgAAEIAABCEAAASQHIAABCEAAAhCAQMQIIIARu+B0FwIQgAAEIAABCCCA5AAEIAABCEAAAhCIGAEEMGIXnO5CAAIQgAAEIAABBJAcgAAEIAABCEAAAhEjgABG7ILTXQhAAAIQgAAEIIAAkgMQgAAEIAABCEAgYgQQwIhdcLoLAQhAAAIQgAAEEEByAAIQgAAEIAABCESMAAIYsQtOdyEAAQhAAAIQgAACSA5AAAIQgAAEIACBiBFAACN2wekuBCAAAQhAAAIQQADJAQhAAAIQgAAEIBAxAghgxC443YUABCAAAQhAAAIIIDkAAQhAAAIQgAAEIkYAAYzYBae7EIAABCAAAQhAAAEkByAAAQhAAAIQgEDECCCAEbvgdBcCEIAABCAAAQgggOQABCAAAQhAAAIQiBgBBDBiF5zuQgACEIAABCAAAQSQHIAABCAAAQhAAAIRI4AARuyC010IQAACEIAABCCAAJIDEIAABCAAAQhAIGIEEMCIXXC6CwEIQAACEIAABBBAcgACEIAABCAAAQhEjAACGLELTnchAAEIQAACEIAAAkgOQAACEIAABCAAgYgRQAAjdsHpLgQgAAEIQAACEEAAyQEIQAACEIAABCAQMQIIYMQuON2FAAQgAAEIQAACCCA5AAEIQAACEIAABCJGAAGM2AWnuxCAAAQgAAEIQAABJAcgAAEIQAACEIBAxAgggBG74HQXAhCAAAQgAAEIRF0An5B0jKRDJb0SS4eukm6VtKukZZImSRpGqkAAAhCAAAQgAIFCIRBlATxD0imSDov9MQFsIelLSXdJGi5pG0nPSbpe0s2FctHpBwQgAAEIQAAC0SYQVQHsJOktSd0kzYkbATxT0rWSOkqqiKXG5ZIuk7R1tFOF3kMAAhCAAAQgUCgEoiqAUyQ9IulvMdHzXwGPl7SdpMPjLvDeMVlsLWlloVx4+gEBCEAAAhCAQHQJRFEAL4nN++seu+w20ucL4GRJzSX1jEuJbSVNl1QkaX50U4WeQwACEIAABCBQKASiJoClsdG8PSXNTSKAtR0BNH72unhFoSQE/YAABCAAAQhEhEDL2MBOZUT6u143oyaANsfvDknLJfl930RSmaSHJU2VdJ2kDinOAdxC0rwoJg59hgAEIAABCBQAAVsT8G0B9KPWXYiaADaV1DaBkgncyZJelLRW0hexVcCjJG0l6RlJNjKYbBVwK5PHuXPnqlUr+082FwL9+/fX6NGjXQ5BrCQ4Zi4NYAnLzBHIzJHIycxwXL58uYqKbGaXbH6/DQpFbouaACa7wOviysDYz3eUNDFWB9BGBm+TNKKGzPAEsKysDAHMwK3Tu3dvjR9vrs3mQgCOLvTWj4UlLDNHIDNHIiczw9EEsHVrcz8EMDNEo3cUBDCD15xfbJmBCcfMcLSjwBKWmSOQmSORk5nhiAD+Mg8uM0SjdxQEMIPXfMqUKere3V+cncEDR+xQcMzcBYclLDNHIDNHIiczwxEBRABdMwkBdCVIPAQgAAEIQCDHBBBABNA15RBAV4LEQwACEIAABHJMAAFEAF1TDgF0JUg8BEJO4Oeff1Z5eXnIe0HzIVB4BBo3bqymTa34x683BBABdM14BNCVIPEQCDEBk7+SkhItXLgwxL2g6RAoTAKbb765Zs6cmVQCEUAE0DXrEUBXgsRDIMQE/IcItUBDfBFpekES8Ov81VSmDQFEAF0THwF0JUg8BEJMwH+IUAs0xBeRphckgaB7EwFEAF0THwF0JUg8BEJMIOghE+Ku0XQIhJpA0L2JACKArgmOALoSJB4CISYQ9JAJcddoOgRCTSDo3kQAEUDXBEcAXQkSD4EQEwh6yIS4azQdAqEmEHRvIoAIoGuCI4CuBImHQIgJBD1kwti1v//97zr77LO9pn/55Zfaaqut1uvGG2+8oQMPPND7u5deekkHH3ywczdnz57traa+5557dMYZZzgfzz/A/fffr7vvvlsfffSR7Fptttlm6tatmy688MLqPmTsZBk+kLE455xzNGvWLHXu3DnDRy/8wwXdmwggAuh6FyCArgSJh0CICQQ9ZMLYNV8AW7VqpSuuuELDhg1brxvnnnuuHn/8ca1YsUIvvvhiXgpgRUWFTj75ZP3rX//SWWedpaOOOkpt27aVrdZ+5JFH9PTTT2vp0qVq2bJl3l4iuw4mgFbGBAGs/WUKujcRQASw9lm1fgQC6EqQeAiEmEDQQyaMXfMF0MTp9ddf1zfffFPdDat7aKNoJ5xwgjdal68COHLkSA0ZMsQT1WOPPfZXl8FGLm0ksKYiwflw3RBAt6sQdG8igAigW4ZJCKArQeIhEGICQQ+ZMHbNFw+TpEMPPVT2ynfffff1uvLAAw/ooosu0kMPPeSNqiW+Ar7vvvt0/fXX64svvlCLFi10+OGHa9y4cbKCvP62atUq9enTxxuJW716tQ455BBdffXV2m+//X71CjiV4yUyXrNmjSepdjwbAQza/vOf/+jaa6/Vu+++qyVLlnijbccff7wGDRq0niBOmTJFw4cP1/Tp07Vu3TptscUWOu200zRw4EDvFL4w24hd/Gavy+vXr69XXnnF+2vrc79+/Tx5tte7xmn33XfXddddp9/85jfVoQhg0JXb8M+D7k0EEAF0yzAE0JUf8RAINYGgh0wYO+eLx1dffSV73WtScvvtt3tdMaFr376992ryoIMOWk8A77zzTk8Oe/bsqdNPP13z58/3RGfjjTfWhx9+qGbNmnnHsJ89+uijGjp0qHbbbTdPhEwo582b583X8+cApnq8RMbvvPOOJ6wWf9555wVegn/+85/6/PPPtcsuu3gyZoJnomfiZsJrm0nddtttp5NOOsmTPvvEmPGZMWOGxowZ4+1j8yZtxNT+Ln4zTvXq1asWQMuZq666Socddpgnxj/88IMmTpyoDz74wGuH8bUNAQy8dBvcIejeRAARQLcMQwBd+REPgVATCHrIhLFz8QJoQmOysmDBgurRMRsJa9CgwXoCaHPuOnbsqB133NGTQn97++23vZG4W265RZdeeqm3qGT77bf3pMlG/fztkksu0R133FEtgKkeLxlfG1k0CX3++ec9yartZqN7JqRnnnmmFi1a5AmsvUo2+bOC3yaJybZUBTAx1vpqo4I2ajlixAhv3iUCWNur9uv9g+5NBBABdM0yXgG7EiQeAiEmEPSQie9aZaW0YkV2O2trGurVcztHvADaaJSNUtnf2evKm2++WXPmzPFGuuJHAD/77DPtsMMOmjx5sjc6GL/Z6l4b6bNRv3/84x/eSJnNKywuLq7ezV9Z7K8CTvV4mRBAW8xicwZN8myRiL1Cts1G7Ww0cY899vDaa/2z19XWv/3331/t2rVb7/S1EUCT1PHjx3uvyk0q/fPZ6mQbDUQA3XLYooPuTQQQAXTNMgTQlSDxEAgxgaCHTHzXli+XWrfObmfNJVrZbyWHLV4AS0tLdeqpp2rlypWeAB5xxBHe6F2iAPojfc8884z3mjh+23vvvb3Xvy+//LI3H9BeC9vxNtpoo+rdTITsFasvgKkeL1k3a/sK2Ob72fw8G33beeed1bx5c7333nveiOWrr77qyZ5t1mebK2j/a4thTAzt//s/T1UAbQXyMccc44nwiSeeqE033dSbI2jcjjzySN11110IoEP++qFB9yYCiAC6phkC6EqQeAiEmEDQQya+a2EcATQBtFe+JiaVlZX65JNPPFGraQTwb3/7W3UNQb/v8SOA9957r7dYItURwKDjJUud2iwCsVev9krX5vyZmPqbzUW0+YPxAuj/zI5vgmqLRD7++GNPjK3EzMUXX+yVl7G5jPFb165dPcnzF4HYHEKb72fS629r1671hNjmRyKAmfmFEHRvIoAIoGumIYCuBImHQIgJBD1kwti1xBFAm6NmYmJz4f76179Wj4ZZAWi/DIztY6tiTXZMGP1t6tSpXrkVi7N5fv4cwNGjR+uaa66p3s/kyRZt+ItAUj1eTXxHjRqlwYMHe6+djzvuuF/t5peBKS8vV5s2bbyRvPg5iQcccIDeeuutpALoH8xkz0rMvP/++9p11101duxYTwoXLlyoTTbZxNvNRNfmPNqiFF8ArT0mf7bYxN9M+kw4TY4RwMzcNUH3JgKIALpmGgLoSpB4CISYQNBDJoxdSxTAZH1IHAG0fSZNmuStAj7llFO8lbI2EmYlUkywbBWw/8rXVvnaHDir02flT1544QXv/9v8u/hVwKkeL1n7TCBtIcgTTzzhLebo0aOHN0pnbXrsscf05JNPVheC3meffbyVu1aGxUbqTMBsZM/kzR8BtAUqNk/RXoEXFRV5i0NM+L777jtvNXCTJk28/bfddltvnmDv3r2r97GC09tss021AJromvDaYg8rpWOjgSbIP/30k/dqGAHMzF0TdG8igAiga6YhgK4EiYdAiAkEPWTC2LVUBTB+BNDvp5VNMZGycib2atVeHdvomq1w9TebP2d1AB9++GHZCJwJk40G2khhvADa/qkcb0OMLd6E6r///a8379CvD9irVy+Z+Nlmi1pMyGzEzyTVviDyhz/8wZMzXwCtRqD1w0T2+++/92TSVjfbvMGtt966uglPPfWUJ70mgyZ9xsJGO21Bic2BtM1epZv8WruWLVvmSfBNN92kP/7xj97CGnvtbRtlYNzunqB7EwFEAN0yjDIwrvyIh0CoCQQ9ZELdORoPgRATCLo3EUAE0DW9GQF0JUg8BEJMIOghE+Ku0XQIhJpA0L2JACKArgmOALoSJB4CISYQ9JAJcddoOgRCTSDo3kQAEUDXBEcAXQkSD4EQEwh6yIS4azQdAqEmEHRvIoAIoGuCI4CuBImHQIgJBD1kQtw1mg6BUBMIujcRQATQNcERQFeCxEMgxASCHjIh7hpNh0CoCQTdmwggAuia4AigK0HiIRBiAkEPmRB3jaZDINQEgu5NBBABdE1wBNCVIPEQCDGBoIdMiLtG0yEQagJB9yYCiAC6JjgC6EqQeAiEmEDQQybEXaPpEAg1gaB7EwFEAF0THAF0JUg8BEJMIOghE+Ku0XQIhJpA0L2JACKArgmOALoSJB4CISYQ9JAJcddoOgRCTSDo3kQAEUDXBEcAXQkSD4EQEwh6yISxa/YN2rPPPttr+pdffqmtttpqvW688cYbOvDAA72/e+mll2TfBHbdZs+erZKSEt1zzz0644wzXA/ntd/60alTJ+9bv4nbsGHDZH/sG71r1qxR/fr1nc+Z6gF8vl9//bVKS0tTDcv4fuvWrdPtt9/ucfrss8+842+//fY655xzdP755+eUScY7Jyno3kQAEUDXvEMAXQkSD4EQEwh6yISxa76gtGrVSldccYUnSvHbueeeq8cff1wrVqzQiy++mLcC+Oijj2r16tV64YUXdNBBB63XB5PaxYsXe32oCwE0yfrqq6/qTACtzz169NDrr7+uyy67TN27d/f4PPvss/rrX/+qI444Qv/85z89QQ7rFnRvIoAIoGtub1AAKysrtaJ8hes5iIcABPKUgD1EitoXqaysTCZMhbD5AnjWWWd5gvDNN99Ud+vnn3/WZpttphNOOMEbrctnAXz55Ze17bbbeqOAd911V3Uf3nrrLR1wwAE688wzvdGvQhTA8vJyNW7cuMZ0HDhwoMaMGaN///vfOvzww9fbz8TPru+oUaPUr1+/vE7piooK2XO2QYMGv2qnL3hzv5+b9N70711JrW3AMK87mqXGhVfvswSklofdoAAuX71crcdabrFBAAIFSeBnSWNVcAJoI1T2evfQQw+VvfLdd999vcv3wAMP6KKLLtJDDz2ko4466levgO+77z5df/31+uKLL9SiRQtPLsaNG6fNN9+8+vKvWrVKffr00SOPPOKN0B1yyCG6+uqrtd9++/3qFXAqx0uWV/YK2ARw9OjRuuSSS/T999+radOm3q4XXnih92rbXmMPHz78VwJ45513auLEidV9OOaYY3Tddddp4403rj6VvTIeMGCA93e33HKLFi1a5I0ymhSbkFx66aWaMmWKJx7239dcc011rEmn8X3ttdc0fvx4j2GTJk30pz/9yWPnt9MCjNXQoUNlo5nffvuttthiC5133nmemPmjcybpdm4blX3uuef05JNPau3atfrhhx+S3nK+xBt3k71km40Ifvjhh1q4cKH3Y+unSaPfj48++ki/+93vPIavvPJK9SHsOtsIscmj/cNh66231qRJkzRr1iz97W9/8/pj8n3bbbepQ4cO653aXkfb39u1admypY499liPe+vWVc9Qe2XdqFEjDR482ONl12nevHmytuywww41CqD6Sqq69OtvsXsXASzI38w56RQjgDnBzEkgkJ8ECnUE0H9FaQ/z3/zmN95cMdtM6Nq3b+8JjElH/BxAeyCbHPbs2VOnn3665s+f74mKyYPJRLNmzbxj2M9MaExsdtttN28U0YTSHuZ333139RzAVI+3IQE0EbX2moSYYJlwmnjccMMN3tzARAHs27evJ2V//vOf9fvf/96TLhO9oqIiTZ06tVq6TAC7dOmiHXfc0RPM7777zntdvs8++3ivle0V6l577eX184477vBerf7hD3/wmuqPsHbu3FknnXSSd57333/fe9V+6qmnVo9WmvCYYH3++eee9Ni53n33Xa/NJpUmR7b5AmhyaNfHRu9M8o4++uikN82bb77pSZgJmT/XM3HHCRMm6PLLL/fateuuu+rII4/0BOz555/3djVGgwYN8mR36dKlnpB9+umnXhv9nPAFsLi42JN769uCBQvUu3dvTx7tuvvbVVdd5Ym0/cz+0WG50L9/f+8VuY3Yxgtgx44dtc0223jts5yy9m2yySY1CiAjgDX/7oziCOBgSTbLeFNJ5ZL+T/L+jfBxHKYKSfbvg7Wqek1eKWlvSdMTUDIHMD+fy7QKAjkhEDTPKCeNyPBJ/BEqm6NmcmEPZ3twL1myRCYtNrJlr9ziBdBexdmD2RcAv0lvv/229/C3h7tJi43u2EIDe/1oo37+ZhJlouQLYKrHq6nr/gigSZ696rUROpMwG3U0ebWRLZPAeAG0hShbbrmlJ2Imff72zjvveCOgNrLmS5UJoEmISY+/gMRGNW+88cb1Xp2aNBkXGy014YoXwIsvvlgmWv5mo5VDhgzxFmTYHMV7771X9ho+fgTW9rX9rN0mSZtuumm1AB533HF67LHHArPBRnFNwk3UEudG+sHPPPOMN0fQRghtJM5GJo2LyV7Dhg29n5nY2at1e41sx7G5g3ZNbR8bxfQF0ITO5mH627XXXuvJnUmztX/GjBkeSxs1/Mtf/lK9ny+qdnwTan8E0GTcjm3t2NAWdG8yBzCacwC3lvS9pDJJlkGXS7LxeRuPNtGzzQTwEEmvBtxNCGDgrxt2gEDhEgh6yMT3PBdzgls2buk8cT9eAG30zF7r2d/Za7ybb77ZGznzR5380R6TFnsNN3nyZE+w4jdb3WsjfTYa9o9//MMbdbIHuAmEv/kri/1VwKkeLxUBtFfBNjJmwmQjmvZa9v777/eEJl4Are32ethW55ro+ptdNxthspWxJkK2mfT16tVLt956a/V+NspoI6D+qJn/A5PH5s2bV0uQz9fa5a+mtn1NhEz87LX3KaecotNOO80bdTQRj99sNHXPPffUU0895Ymlfy2MrcXEbyZN/mavjK3d6QigndOuoUnZ3nvvrbZt23rHsZFA+/8jRozQ8ccf7y2ssfbY5gugP6Lqt8NE3ATygw8+8EYC7bWv/ePA8stkOZ57mzZtvJ+NHTu2WgAvuOCC6hHpDf1mCbo3EcBoCmB8zjSRdLGkGyS1l7Qk9kMTwEMl/TK5IXmmIYCF+2ynZxAIJBD0kIk/QC7mBJf1LVOrJm6LUeIF0F7B2au7lStXeg9oG4mx0btEAfRH+mzkKHFRgQmCvaoz4bH5gPZa2I630UYbVeOxV7Xbbbdd9RzAVI+XigCawJls2qtpkxEbUbLXrokCaCNrNs8t2WbyZOVpbITSF0Db1wTS3xK5+X9vo2MmYia5tvn7ffLJJ16f/e3HH3/05r7ZCJmNpFkbTbBrao+Nvtnopn8t7JWqzevzN+N92GGHVf9/GzGzxSG+bNfmFbAvwfaK1trVrVs3b46h/YPA5h3aa1obzbMVxTaKGS+AiaV9rF12DJNJe2VuDG06QE39tH9QmFz7I4B2fP8cCGDgr6gN7hDFV8AG5AhJ98cmf5rs3Sjpl/cRVSOANvu1kaTZkmwCzOQkJBFAt/wjGgKhJlAbAQzjCKAJoL3ytTlg1n5fWmoaAUwmFfEjgP5rzVRHAIOOl4oA2j4mnTZnzlYw20igCV2iANoraHsVbSJlI0+Jm40C2ry/TAlgTSOANjppsmp/bJTMRk6NfeJmUmsjcYnXIl4oTaz9zfq8yy67ePMDbWTXZPGJJ55IitAEzUb97DWtv8LWXgVbvtvP/vWvf8lejdsfG8W0vuy///7ewhb739oIoD/f0BaTmAAnbiaWNiLrC6DJos2JDNqC7k1GABkBtLv8TEnzJD0el1BWNGqqLTySZP+EMlm09fB3JCQdAhh0F/JzCBQwgaCHTBi7njiSZfPxbM6YLeaweV62mXRYAWi/DIztY4sQunbt6gmjv9krTBstsjiTK38OoI22xa+Mtflwtugjfg5gKsdLVQDtNarNLzN5sde0tiUKoL2CtQUv1o6aFkf457NXqS4jgHZ8a4etNvY3mwNncmOLPmwuol0He905bdo0b45cTVvitUgl52wOno3G2mtkG9WN32w18YknnqiRI0d6c/X8zeZxGsPdd9/dm9dp7TUps7ywV9J2rZctW+at1K2NANq1sZFQu/aWZzVtCGAqV7Z2+0R1BDCekjFYKmk/SdNqwGdj2iaC3RDA2iUYe0OgkAlEQQCTXb9ko07+HDh//pqNtJkk2WiajSb5r3ztVaotxrDXeCYTtkDA/v/cuXPXWwWc6vGStS9+EUhN+ZcogLafLf646aabvHlntlLWFjPYnEd7FWtzAO3vbMuEAMavAn7vvfe8V6EmQDYX0TYr5WKvcE2QbIHJzjvv7L3CtTmKTz/9tDcKZ+2raQRwQ/ddfCFo66utULZRRpufZyNy9v9tdDD+CykmotYGG0k0ybfFHbaZQNrqYBtRjF/Z688BTPYK2Pplr43tFbBtJpZ2XnuFbCOItqrYuNvx7B8ONo8SAcz8b1IEsGohiC0IsX96JC+KJNl4s5VKryqG9cvmjQDaZGC/6KbVT/Krqmf+cnFECEAgnwhEWQDjRwD9a2ILA+xVq41iWR1Ae3Vsc9rs1au/2StIE5qHH37YExoTBxsNtJHC+DIwtn8qx6tJAO2Voq3s3ZAA2uIFa0O86NgrWJMREx6THVt1am20EjH+IgV7LWpyG/+VlA3NAbQRUn9xhL+f/X9bVGLttOeHibOxM/nxN2ubLYCwMjkzZ870FpPY6KAt/jBZtXanMwJox0/nU3D26tjmb9r8P79eofXBBM5GDOMLR5sA2shl4jVNnAPo99WmB9iIqHE3vj53O6YtRLL2GicbJbUSNEFbsnvTxNUfoTa2sVXYFIIOgllAP7dVvw/FVgK3kzRK0gmSbDbud5J2iZV+sdFAfzXwg6qSwF/W7FcB4RVwASUGXYFAbQkUogDWlgH7QyAfCQTdm8wBjOYcwKcl7SapRezzLx9IsqVcH8aS+ChJ4yR1itUBtH9C2kSNSUmSHAHMxzufNkEgRwSCHjI5agangQAEEggE3ZsIYDQFMJM3CgKYSZocCwIhIxD0kAlZd2guBAqGQNC9iQAigK7JjgC6EiQeAiEmEPSQCXHXaDoEQk0g6N5EABFA1wRHAF0JEg+BEBMIesiEuGs0HQKhJhB0byKACKBrgiOArgSJh0CICQQ9ZELcNZoOgVATCLo3EUAE0DXBEUBXgsRDIMQEgh4yIe4aTYdAqAkE3ZsIIALomuAIoCtB4iEQYgJBD5kQd42mQyDUBILuTQQQAXRNcATQlSDxEAgxgaCHTIi7RtMhEGoCQfcmAogAuiY4AuhKkHgIhJhA0EMmxF2j6RAINYGgexMBRABdExwBdCVIPARCTCDoIRPirtF0CISaQNC9iQAigK4JjgC6EiQeAiEmEPSQCWvX7Hu1Z599dtLmt2nTxvsWLBsE8plA0L2JACKArvmLALoSJB4CISYQ9JAJa9dMAM855xw99thj2mKLLdbrRsOGDfW73/0urF2j3REhEHRvIoAIoOutgAC6EiQeAiEmEPSQCWvXfAH86quvVFpaGtZu0O4IEwi6NxFABND19kAAXQkSD4EQEwh6yIS1a0EC+J///Ed77LGHnnrqKR111FHrdfOSSy7R448/rvnz56tBgwZau3athg4dqvvvv9/7u44dO+q0007TkCFDZKOJbBDIBoGgexMBRABd8w4BdCVIPARCTCDoIRPWrvkC+Pnnn/9qBLB+/fqqV6+etttuO+2888566KGHqru5Zs0adejQwRO8m266yfv7U045xXuVPGDAAO27776aOnWqRo4cqZNOOkn33XdfWBHR7jwnEHRvIoAIoGsKI4CuBImHQIgJBD1kwtq1DS0CsRE/G/kbPXq0Ro0apYULF6ply5ZeV5988kkdf/zxev/997XrrjH5zCQAACAASURBVLtq+vTp2mmnnTRs2DANGjSoGofFDR48WB9//LF23HHHsGKi3XlMIOjeRAARQNf0RQBdCRIPgRATCHrIrNe1ykppxYrs9tZErF4953P4I4AmdImLQGwVsM0LnDNnjkpKSjRp0iRvwYhtJn+fffaZPv30U+//33bbbbr00kuVOJdw9uzZXuytt96qXr16ObeXA0AgkUDQvYkAIoCudw0C6EqQeAiEmEDQQ2a9ri1fLrVund3elpVJrezXktsWNAfQP/pBBx3k/eerr76qsrIybb755t7cvr59+3p/74/0rVy5UhtttFF1o1avXu39/8SRQbdWEw2BXwgE3ZsIIALoer8ggK4EiYdAiAkEPWTW61oIRwCDVgHfdddduuCCCzRz5kw999xzsgUg9t9FRUVe1/0RwK+//tob8fM3RgBDnPQhaXrQvYkAIoCuqYwAuhIkHgIhJhD0kAlr11IdAVyxYoU36jdw4EBPAG3Vr40G+ps/B9BGAvv161f99/7I4P/+9z/tsMMOYcVEu/OYQNC9iQAigK7piwC6EiQeAiEmEPSQCWvX/EUgjz76qDp16vSrbuy+++6y1cC29ezZU2+++aa3GGTy5Mk666yz1tv/1FNPrV4FvM8++1SvAj755JN17733hhUR7c5zAkH3JgKIALqmMALoSpB4CISYQNBDJqxd80cAa2r/okWL1LZtW+/Hzz77rHr06OHN6VuwYEH1imA/1uoADh8+3JM9vw7gGWec4a0CthFDNghkg0DQvYkAIoCueYcAuhIkHgIhJhD0kAlx12g6BEJNIOjeRAARQNcERwBdCRIPgRATCHrIhLhrNB0CoSYQdG8igAiga4IjgK4EiYdAiAkEPWRC3DWaDoFQEwi6NxFABNA1wRFAV4LEQyDEBIIeMiHuGk2HQKgJBN2bCCAC6JrgCKArQeIhEGICQQ+ZEHeNpkMg1ASC7k0EEAF0TXAE0JUg8RAIMYGgh0yIu0bTIRBqAkH3JgKIALomOALo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\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure()\n",
"minutes = np.arange(1, 61)\n",
"start_date = datetime(2016, 4, 15, 9, 0)\n",
"\n",
"for label, car_share in car_shares.items():\n",
" values = np.array([car_share.calculate_trip_cost(start_date,\n",
" start_date + timedelta(minutes=int(m)),\n",
" 100)\n",
" for m in minutes])\n",
" plt.plot(minutes, values, '-', label=label)\n",
"\n",
"plt.ylabel('Cost in $')\n",
"plt.xlabel('Rental time (minutes)')\n",
"\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"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.0"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment