Format: application/octet-stream
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "---\n",
8 "\n",
9 "_You are currently looking at **version 1.0** of this notebook. To download notebooks and datafiles, as well as get help on Jupyter notebooks in the Coursera platform, visit the [Jupyter Notebook FAQ](https://www.coursera.org/learn/python-machine-learning/resources/bANLa) course resource._\n",
10 "\n",
11 "---"
12 ]
13 },
14 {
15 "cell_type": "markdown",
16 "metadata": {},
17 "source": [
18 "# Applied Machine Learning: Module 2 (Supervised Learning, Part I)"
19 ]
20 },
21 {
22 "cell_type": "markdown",
23 "metadata": {},
24 "source": [
25 "## Preamble and Review"
26 ]
27 },
28 {
29 "cell_type": "code",
30 "execution_count": 1,
31 "metadata": {},
32 "outputs": [
33 {
34 "name": "stdout",
35 "output_type": "stream",
36 "text": [
37 "Accuracy of K-NN classifier on training set: 0.95\n",
38 "Accuracy of K-NN classifier on test set: 1.00\n",
39 "Predicted fruit type for [[5.5, 2.2, 10, 0.7]] is orange\n"
40 ]
41 }
42 ],
43 "source": [
44 "%matplotlib notebook\n",
45 "import numpy as np\n",
46 "import pandas as pd\n",
47 "import seaborn as sn\n",
48 "import matplotlib.pyplot as plt\n",
49 "\n",
50 "from sklearn.model_selection import train_test_split\n",
51 "from sklearn.neighbors import KNeighborsClassifier\n",
52 "\n",
53 "np.set_printoptions(precision=2)\n",
54 "\n",
55 "\n",
56 "fruits = pd.read_table('fruit_data_with_colors.txt')\n",
57 "\n",
58 "feature_names_fruits = ['height', 'width', 'mass', 'color_score']\n",
59 "X_fruits = fruits[feature_names_fruits]\n",
60 "y_fruits = fruits['fruit_label']\n",
61 "target_names_fruits = ['apple', 'mandarin', 'orange', 'lemon']\n",
62 "\n",
63 "X_fruits_2d = fruits[['height', 'width']]\n",
64 "y_fruits_2d = fruits['fruit_label']\n",
65 "\n",
66 "X_train, X_test, y_train, y_test = train_test_split(X_fruits, y_fruits, random_state=0)\n",
67 "\n",
68 "from sklearn.preprocessing import MinMaxScaler\n",
69 "scaler = MinMaxScaler()\n",
70 "X_train_scaled = scaler.fit_transform(X_train)\n",
71 "# we must apply the scaling to the test set that we computed for the training set\n",
72 "X_test_scaled = scaler.transform(X_test)\n",
73 "\n",
74 "knn = KNeighborsClassifier(n_neighbors = 5)\n",
75 "knn.fit(X_train_scaled, y_train)\n",
76 "print('Accuracy of K-NN classifier on training set: {:.2f}'\n",
77 " .format(knn.score(X_train_scaled, y_train)))\n",
78 "print('Accuracy of K-NN classifier on test set: {:.2f}'\n",
79 " .format(knn.score(X_test_scaled, y_test)))\n",
80 "\n",
81 "example_fruit = [[5.5, 2.2, 10, 0.70]]\n",
82 "print('Predicted fruit type for ', example_fruit, ' is ', \n",
83 " target_names_fruits[knn.predict(example_fruit)[0]-1])"
84 ]
85 },
86 {
87 "cell_type": "markdown",
88 "metadata": {},
89 "source": [
90 "## Datasets"
91 ]
92 },
93 {
94 "cell_type": "code",
95 "execution_count": 2,
96 "metadata": {
97 "scrolled": false
98 },
99 "outputs": [
100 {
101 "data": {
102 "application/javascript": [
103 "/* Put everything inside the global mpl namespace */\n",
104 "/* global mpl */\n",
105 "window.mpl = {};\n",
106 "\n",
107 "mpl.get_websocket_type = function () {\n",
108 " if (typeof WebSocket !== 'undefined') {\n",
109 " return WebSocket;\n",
110 " } else if (typeof MozWebSocket !== 'undefined') {\n",
111 " return MozWebSocket;\n",
112 " } else {\n",
113 " alert(\n",
114 " 'Your browser does not have WebSocket support. ' +\n",
115 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
116 " 'Firefox 4 and 5 are also supported but you ' +\n",
117 " 'have to enable WebSockets in about:config.'\n",
118 " );\n",
119 " }\n",
120 "};\n",
121 "\n",
122 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
123 " this.id = figure_id;\n",
124 "\n",
125 " this.ws = websocket;\n",
126 "\n",
127 " this.supports_binary = this.ws.binaryType !== undefined;\n",
128 "\n",
129 " if (!this.supports_binary) {\n",
130 " var warnings = document.getElementById('mpl-warnings');\n",
131 " if (warnings) {\n",
132 " warnings.style.display = 'block';\n",
133 " warnings.textContent =\n",
134 " 'This browser does not support binary websocket messages. ' +\n",
135 " 'Performance may be slow.';\n",
136 " }\n",
137 " }\n",
138 "\n",
139 " this.imageObj = new Image();\n",
140 "\n",
141 " this.context = undefined;\n",
142 " this.message = undefined;\n",
143 " this.canvas = undefined;\n",
144 " this.rubberband_canvas = undefined;\n",
145 " this.rubberband_context = undefined;\n",
146 " this.format_dropdown = undefined;\n",
147 "\n",
148 " this.image_mode = 'full';\n",
149 "\n",
150 " this.root = document.createElement('div');\n",
151 " this.root.setAttribute('style', 'display: inline-block');\n",
152 " this._root_extra_style(this.root);\n",
153 "\n",
154 " parent_element.appendChild(this.root);\n",
155 "\n",
156 " this._init_header(this);\n",
157 " this._init_canvas(this);\n",
158 " this._init_toolbar(this);\n",
159 "\n",
160 " var fig = this;\n",
161 "\n",
162 " this.waiting = false;\n",
163 "\n",
164 " this.ws.onopen = function () {\n",
165 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
166 " fig.send_message('send_image_mode', {});\n",
167 " if (fig.ratio !== 1) {\n",
168 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
169 " }\n",
170 " fig.send_message('refresh', {});\n",
171 " };\n",
172 "\n",
173 " this.imageObj.onload = function () {\n",
174 " if (fig.image_mode === 'full') {\n",
175 " // Full images could contain transparency (where diff images\n",
176 " // almost always do), so we need to clear the canvas so that\n",
177 " // there is no ghosting.\n",
178 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
179 " }\n",
180 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
181 " };\n",
182 "\n",
183 " this.imageObj.onunload = function () {\n",
184 " fig.ws.close();\n",
185 " };\n",
186 "\n",
187 " this.ws.onmessage = this._make_on_message_function(this);\n",
188 "\n",
189 " this.ondownload = ondownload;\n",
190 "};\n",
191 "\n",
192 "mpl.figure.prototype._init_header = function () {\n",
193 " var titlebar = document.createElement('div');\n",
194 " titlebar.classList =\n",
195 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
196 " var titletext = document.createElement('div');\n",
197 " titletext.classList = 'ui-dialog-title';\n",
198 " titletext.setAttribute(\n",
199 " 'style',\n",
200 " 'width: 100%; text-align: center; padding: 3px;'\n",
201 " );\n",
202 " titlebar.appendChild(titletext);\n",
203 " this.root.appendChild(titlebar);\n",
204 " this.header = titletext;\n",
205 "};\n",
206 "\n",
207 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
208 "\n",
209 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
210 "\n",
211 "mpl.figure.prototype._init_canvas = function () {\n",
212 " var fig = this;\n",
213 "\n",
214 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
215 " canvas_div.setAttribute(\n",
216 " 'style',\n",
217 " 'border: 1px solid #ddd;' +\n",
218 " 'box-sizing: content-box;' +\n",
219 " 'clear: both;' +\n",
220 " 'min-height: 1px;' +\n",
221 " 'min-width: 1px;' +\n",
222 " 'outline: 0;' +\n",
223 " 'overflow: hidden;' +\n",
224 " 'position: relative;' +\n",
225 " 'resize: both;'\n",
226 " );\n",
227 "\n",
228 " function on_keyboard_event_closure(name) {\n",
229 " return function (event) {\n",
230 " return fig.key_event(event, name);\n",
231 " };\n",
232 " }\n",
233 "\n",
234 " canvas_div.addEventListener(\n",
235 " 'keydown',\n",
236 " on_keyboard_event_closure('key_press')\n",
237 " );\n",
238 " canvas_div.addEventListener(\n",
239 " 'keyup',\n",
240 " on_keyboard_event_closure('key_release')\n",
241 " );\n",
242 "\n",
243 " this._canvas_extra_style(canvas_div);\n",
244 " this.root.appendChild(canvas_div);\n",
245 "\n",
246 " var canvas = (this.canvas = document.createElement('canvas'));\n",
247 " canvas.classList.add('mpl-canvas');\n",
248 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
249 "\n",
250 " this.context = canvas.getContext('2d');\n",
251 "\n",
252 " var backingStore =\n",
253 " this.context.backingStorePixelRatio ||\n",
254 " this.context.webkitBackingStorePixelRatio ||\n",
255 " this.context.mozBackingStorePixelRatio ||\n",
256 " this.context.msBackingStorePixelRatio ||\n",
257 " this.context.oBackingStorePixelRatio ||\n",
258 " this.context.backingStorePixelRatio ||\n",
259 " 1;\n",
260 "\n",
261 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
262 "\n",
263 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
264 " 'canvas'\n",
265 " ));\n",
266 " rubberband_canvas.setAttribute(\n",
267 " 'style',\n",
268 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
269 " );\n",
270 "\n",
271 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
272 " if (this.ResizeObserver === undefined) {\n",
273 " if (window.ResizeObserver !== undefined) {\n",
274 " this.ResizeObserver = window.ResizeObserver;\n",
275 " } else {\n",
276 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
277 " this.ResizeObserver = obs.ResizeObserver;\n",
278 " }\n",
279 " }\n",
280 "\n",
281 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
282 " var nentries = entries.length;\n",
283 " for (var i = 0; i < nentries; i++) {\n",
284 " var entry = entries[i];\n",
285 " var width, height;\n",
286 " if (entry.contentBoxSize) {\n",
287 " if (entry.contentBoxSize instanceof Array) {\n",
288 " // Chrome 84 implements new version of spec.\n",
289 " width = entry.contentBoxSize[0].inlineSize;\n",
290 " height = entry.contentBoxSize[0].blockSize;\n",
291 " } else {\n",
292 " // Firefox implements old version of spec.\n",
293 " width = entry.contentBoxSize.inlineSize;\n",
294 " height = entry.contentBoxSize.blockSize;\n",
295 " }\n",
296 " } else {\n",
297 " // Chrome <84 implements even older version of spec.\n",
298 " width = entry.contentRect.width;\n",
299 " height = entry.contentRect.height;\n",
300 " }\n",
301 "\n",
302 " // Keep the size of the canvas and rubber band canvas in sync with\n",
303 " // the canvas container.\n",
304 " if (entry.devicePixelContentBoxSize) {\n",
305 " // Chrome 84 implements new version of spec.\n",
306 " canvas.setAttribute(\n",
307 " 'width',\n",
308 " entry.devicePixelContentBoxSize[0].inlineSize\n",
309 " );\n",
310 " canvas.setAttribute(\n",
311 " 'height',\n",
312 " entry.devicePixelContentBoxSize[0].blockSize\n",
313 " );\n",
314 " } else {\n",
315 " canvas.setAttribute('width', width * fig.ratio);\n",
316 " canvas.setAttribute('height', height * fig.ratio);\n",
317 " }\n",
318 " canvas.setAttribute(\n",
319 " 'style',\n",
320 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
321 " );\n",
322 "\n",
323 " rubberband_canvas.setAttribute('width', width);\n",
324 " rubberband_canvas.setAttribute('height', height);\n",
325 "\n",
326 " // And update the size in Python. We ignore the initial 0/0 size\n",
327 " // that occurs as the element is placed into the DOM, which should\n",
328 " // otherwise not happen due to the minimum size styling.\n",
329 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
330 " fig.request_resize(width, height);\n",
331 " }\n",
332 " }\n",
333 " });\n",
334 " this.resizeObserverInstance.observe(canvas_div);\n",
335 "\n",
336 " function on_mouse_event_closure(name) {\n",
337 " return function (event) {\n",
338 " return fig.mouse_event(event, name);\n",
339 " };\n",
340 " }\n",
341 "\n",
342 " rubberband_canvas.addEventListener(\n",
343 " 'mousedown',\n",
344 " on_mouse_event_closure('button_press')\n",
345 " );\n",
346 " rubberband_canvas.addEventListener(\n",
347 " 'mouseup',\n",
348 " on_mouse_event_closure('button_release')\n",
349 " );\n",
350 " // Throttle sequential mouse events to 1 every 20ms.\n",
351 " rubberband_canvas.addEventListener(\n",
352 " 'mousemove',\n",
353 " on_mouse_event_closure('motion_notify')\n",
354 " );\n",
355 "\n",
356 " rubberband_canvas.addEventListener(\n",
357 " 'mouseenter',\n",
358 " on_mouse_event_closure('figure_enter')\n",
359 " );\n",
360 " rubberband_canvas.addEventListener(\n",
361 " 'mouseleave',\n",
362 " on_mouse_event_closure('figure_leave')\n",
363 " );\n",
364 "\n",
365 " canvas_div.addEventListener('wheel', function (event) {\n",
366 " if (event.deltaY < 0) {\n",
367 " event.step = 1;\n",
368 " } else {\n",
369 " event.step = -1;\n",
370 " }\n",
371 " on_mouse_event_closure('scroll')(event);\n",
372 " });\n",
373 "\n",
374 " canvas_div.appendChild(canvas);\n",
375 " canvas_div.appendChild(rubberband_canvas);\n",
376 "\n",
377 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
378 " this.rubberband_context.strokeStyle = '#000000';\n",
379 "\n",
380 " this._resize_canvas = function (width, height, forward) {\n",
381 " if (forward) {\n",
382 " canvas_div.style.width = width + 'px';\n",
383 " canvas_div.style.height = height + 'px';\n",
384 " }\n",
385 " };\n",
386 "\n",
387 " // Disable right mouse context menu.\n",
388 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
389 " event.preventDefault();\n",
390 " return false;\n",
391 " });\n",
392 "\n",
393 " function set_focus() {\n",
394 " canvas.focus();\n",
395 " canvas_div.focus();\n",
396 " }\n",
397 "\n",
398 " window.setTimeout(set_focus, 100);\n",
399 "};\n",
400 "\n",
401 "mpl.figure.prototype._init_toolbar = function () {\n",
402 " var fig = this;\n",
403 "\n",
404 " var toolbar = document.createElement('div');\n",
405 " toolbar.classList = 'mpl-toolbar';\n",
406 " this.root.appendChild(toolbar);\n",
407 "\n",
408 " function on_click_closure(name) {\n",
409 " return function (_event) {\n",
410 " return fig.toolbar_button_onclick(name);\n",
411 " };\n",
412 " }\n",
413 "\n",
414 " function on_mouseover_closure(tooltip) {\n",
415 " return function (event) {\n",
416 " if (!event.currentTarget.disabled) {\n",
417 " return fig.toolbar_button_onmouseover(tooltip);\n",
418 " }\n",
419 " };\n",
420 " }\n",
421 "\n",
422 " fig.buttons = {};\n",
423 " var buttonGroup = document.createElement('div');\n",
424 " buttonGroup.classList = 'mpl-button-group';\n",
425 " for (var toolbar_ind in mpl.toolbar_items) {\n",
426 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
427 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
428 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
429 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
430 "\n",
431 " if (!name) {\n",
432 " /* Instead of a spacer, we start a new button group. */\n",
433 " if (buttonGroup.hasChildNodes()) {\n",
434 " toolbar.appendChild(buttonGroup);\n",
435 " }\n",
436 " buttonGroup = document.createElement('div');\n",
437 " buttonGroup.classList = 'mpl-button-group';\n",
438 " continue;\n",
439 " }\n",
440 "\n",
441 " var button = (fig.buttons[name] = document.createElement('button'));\n",
442 " button.classList = 'mpl-widget';\n",
443 " button.setAttribute('role', 'button');\n",
444 " button.setAttribute('aria-disabled', 'false');\n",
445 " button.addEventListener('click', on_click_closure(method_name));\n",
446 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
447 "\n",
448 " var icon_img = document.createElement('img');\n",
449 " icon_img.src = '_images/' + image + '.png';\n",
450 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
451 " icon_img.alt = tooltip;\n",
452 " button.appendChild(icon_img);\n",
453 "\n",
454 " buttonGroup.appendChild(button);\n",
455 " }\n",
456 "\n",
457 " if (buttonGroup.hasChildNodes()) {\n",
458 " toolbar.appendChild(buttonGroup);\n",
459 " }\n",
460 "\n",
461 " var fmt_picker = document.createElement('select');\n",
462 " fmt_picker.classList = 'mpl-widget';\n",
463 " toolbar.appendChild(fmt_picker);\n",
464 " this.format_dropdown = fmt_picker;\n",
465 "\n",
466 " for (var ind in mpl.extensions) {\n",
467 " var fmt = mpl.extensions[ind];\n",
468 " var option = document.createElement('option');\n",
469 " option.selected = fmt === mpl.default_extension;\n",
470 " option.innerHTML = fmt;\n",
471 " fmt_picker.appendChild(option);\n",
472 " }\n",
473 "\n",
474 " var status_bar = document.createElement('span');\n",
475 " status_bar.classList = 'mpl-message';\n",
476 " toolbar.appendChild(status_bar);\n",
477 " this.message = status_bar;\n",
478 "};\n",
479 "\n",
480 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
481 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
482 " // which will in turn request a refresh of the image.\n",
483 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
484 "};\n",
485 "\n",
486 "mpl.figure.prototype.send_message = function (type, properties) {\n",
487 " properties['type'] = type;\n",
488 " properties['figure_id'] = this.id;\n",
489 " this.ws.send(JSON.stringify(properties));\n",
490 "};\n",
491 "\n",
492 "mpl.figure.prototype.send_draw_message = function () {\n",
493 " if (!this.waiting) {\n",
494 " this.waiting = true;\n",
495 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
496 " }\n",
497 "};\n",
498 "\n",
499 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
500 " var format_dropdown = fig.format_dropdown;\n",
501 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
502 " fig.ondownload(fig, format);\n",
503 "};\n",
504 "\n",
505 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
506 " var size = msg['size'];\n",
507 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
508 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
509 " fig.send_message('refresh', {});\n",
510 " }\n",
511 "};\n",
512 "\n",
513 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
514 " var x0 = msg['x0'] / fig.ratio;\n",
515 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
516 " var x1 = msg['x1'] / fig.ratio;\n",
517 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
518 " x0 = Math.floor(x0) + 0.5;\n",
519 " y0 = Math.floor(y0) + 0.5;\n",
520 " x1 = Math.floor(x1) + 0.5;\n",
521 " y1 = Math.floor(y1) + 0.5;\n",
522 " var min_x = Math.min(x0, x1);\n",
523 " var min_y = Math.min(y0, y1);\n",
524 " var width = Math.abs(x1 - x0);\n",
525 " var height = Math.abs(y1 - y0);\n",
526 "\n",
527 " fig.rubberband_context.clearRect(\n",
528 " 0,\n",
529 " 0,\n",
530 " fig.canvas.width / fig.ratio,\n",
531 " fig.canvas.height / fig.ratio\n",
532 " );\n",
533 "\n",
534 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
535 "};\n",
536 "\n",
537 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
538 " // Updates the figure title.\n",
539 " fig.header.textContent = msg['label'];\n",
540 "};\n",
541 "\n",
542 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
543 " var cursor = msg['cursor'];\n",
544 " switch (cursor) {\n",
545 " case 0:\n",
546 " cursor = 'pointer';\n",
547 " break;\n",
548 " case 1:\n",
549 " cursor = 'default';\n",
550 " break;\n",
551 " case 2:\n",
552 " cursor = 'crosshair';\n",
553 " break;\n",
554 " case 3:\n",
555 " cursor = 'move';\n",
556 " break;\n",
557 " }\n",
558 " fig.rubberband_canvas.style.cursor = cursor;\n",
559 "};\n",
560 "\n",
561 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
562 " fig.message.textContent = msg['message'];\n",
563 "};\n",
564 "\n",
565 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
566 " // Request the server to send over a new figure.\n",
567 " fig.send_draw_message();\n",
568 "};\n",
569 "\n",
570 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
571 " fig.image_mode = msg['mode'];\n",
572 "};\n",
573 "\n",
574 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
575 " for (var key in msg) {\n",
576 " if (!(key in fig.buttons)) {\n",
577 " continue;\n",
578 " }\n",
579 " fig.buttons[key].disabled = !msg[key];\n",
580 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
581 " }\n",
582 "};\n",
583 "\n",
584 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
585 " if (msg['mode'] === 'PAN') {\n",
586 " fig.buttons['Pan'].classList.add('active');\n",
587 " fig.buttons['Zoom'].classList.remove('active');\n",
588 " } else if (msg['mode'] === 'ZOOM') {\n",
589 " fig.buttons['Pan'].classList.remove('active');\n",
590 " fig.buttons['Zoom'].classList.add('active');\n",
591 " } else {\n",
592 " fig.buttons['Pan'].classList.remove('active');\n",
593 " fig.buttons['Zoom'].classList.remove('active');\n",
594 " }\n",
595 "};\n",
596 "\n",
597 "mpl.figure.prototype.updated_canvas_event = function () {\n",
598 " // Called whenever the canvas gets updated.\n",
599 " this.send_message('ack', {});\n",
600 "};\n",
601 "\n",
602 "// A function to construct a web socket function for onmessage handling.\n",
603 "// Called in the figure constructor.\n",
604 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
605 " return function socket_on_message(evt) {\n",
606 " if (evt.data instanceof Blob) {\n",
607 " /* FIXME: We get \"Resource interpreted as Image but\n",
608 " * transferred with MIME type text/plain:\" errors on\n",
609 " * Chrome. But how to set the MIME type? It doesn't seem\n",
610 " * to be part of the websocket stream */\n",
611 " evt.data.type = 'image/png';\n",
612 "\n",
613 " /* Free the memory for the previous frames */\n",
614 " if (fig.imageObj.src) {\n",
615 " (window.URL || window.webkitURL).revokeObjectURL(\n",
616 " fig.imageObj.src\n",
617 " );\n",
618 " }\n",
619 "\n",
620 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
621 " evt.data\n",
622 " );\n",
623 " fig.updated_canvas_event();\n",
624 " fig.waiting = false;\n",
625 " return;\n",
626 " } else if (\n",
627 " typeof evt.data === 'string' &&\n",
628 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
629 " ) {\n",
630 " fig.imageObj.src = evt.data;\n",
631 " fig.updated_canvas_event();\n",
632 " fig.waiting = false;\n",
633 " return;\n",
634 " }\n",
635 "\n",
636 " var msg = JSON.parse(evt.data);\n",
637 " var msg_type = msg['type'];\n",
638 "\n",
639 " // Call the \"handle_{type}\" callback, which takes\n",
640 " // the figure and JSON message as its only arguments.\n",
641 " try {\n",
642 " var callback = fig['handle_' + msg_type];\n",
643 " } catch (e) {\n",
644 " console.log(\n",
645 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
646 " msg\n",
647 " );\n",
648 " return;\n",
649 " }\n",
650 "\n",
651 " if (callback) {\n",
652 " try {\n",
653 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
654 " callback(fig, msg);\n",
655 " } catch (e) {\n",
656 " console.log(\n",
657 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
658 " e,\n",
659 " e.stack,\n",
660 " msg\n",
661 " );\n",
662 " }\n",
663 " }\n",
664 " };\n",
665 "};\n",
666 "\n",
667 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
668 "mpl.findpos = function (e) {\n",
669 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
670 " var targ;\n",
671 " if (!e) {\n",
672 " e = window.event;\n",
673 " }\n",
674 " if (e.target) {\n",
675 " targ = e.target;\n",
676 " } else if (e.srcElement) {\n",
677 " targ = e.srcElement;\n",
678 " }\n",
679 " if (targ.nodeType === 3) {\n",
680 " // defeat Safari bug\n",
681 " targ = targ.parentNode;\n",
682 " }\n",
683 "\n",
684 " // pageX,Y are the mouse positions relative to the document\n",
685 " var boundingRect = targ.getBoundingClientRect();\n",
686 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
687 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
688 "\n",
689 " return { x: x, y: y };\n",
690 "};\n",
691 "\n",
692 "/*\n",
693 " * return a copy of an object with only non-object keys\n",
694 " * we need this to avoid circular references\n",
695 " * http://stackoverflow.com/a/24161582/3208463\n",
696 " */\n",
697 "function simpleKeys(original) {\n",
698 " return Object.keys(original).reduce(function (obj, key) {\n",
699 " if (typeof original[key] !== 'object') {\n",
700 " obj[key] = original[key];\n",
701 " }\n",
702 " return obj;\n",
703 " }, {});\n",
704 "}\n",
705 "\n",
706 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
707 " var canvas_pos = mpl.findpos(event);\n",
708 "\n",
709 " if (name === 'button_press') {\n",
710 " this.canvas.focus();\n",
711 " this.canvas_div.focus();\n",
712 " }\n",
713 "\n",
714 " var x = canvas_pos.x * this.ratio;\n",
715 " var y = canvas_pos.y * this.ratio;\n",
716 "\n",
717 " this.send_message(name, {\n",
718 " x: x,\n",
719 " y: y,\n",
720 " button: event.button,\n",
721 " step: event.step,\n",
722 " guiEvent: simpleKeys(event),\n",
723 " });\n",
724 "\n",
725 " /* This prevents the web browser from automatically changing to\n",
726 " * the text insertion cursor when the button is pressed. We want\n",
727 " * to control all of the cursor setting manually through the\n",
728 " * 'cursor' event from matplotlib */\n",
729 " event.preventDefault();\n",
730 " return false;\n",
731 "};\n",
732 "\n",
733 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
734 " // Handle any extra behaviour associated with a key event\n",
735 "};\n",
736 "\n",
737 "mpl.figure.prototype.key_event = function (event, name) {\n",
738 " // Prevent repeat events\n",
739 " if (name === 'key_press') {\n",
740 " if (event.which === this._key) {\n",
741 " return;\n",
742 " } else {\n",
743 " this._key = event.which;\n",
744 " }\n",
745 " }\n",
746 " if (name === 'key_release') {\n",
747 " this._key = null;\n",
748 " }\n",
749 "\n",
750 " var value = '';\n",
751 " if (event.ctrlKey && event.which !== 17) {\n",
752 " value += 'ctrl+';\n",
753 " }\n",
754 " if (event.altKey && event.which !== 18) {\n",
755 " value += 'alt+';\n",
756 " }\n",
757 " if (event.shiftKey && event.which !== 16) {\n",
758 " value += 'shift+';\n",
759 " }\n",
760 "\n",
761 " value += 'k';\n",
762 " value += event.which.toString();\n",
763 "\n",
764 " this._key_event_extra(event, name);\n",
765 "\n",
766 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
767 " return false;\n",
768 "};\n",
769 "\n",
770 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
771 " if (name === 'download') {\n",
772 " this.handle_save(this, null);\n",
773 " } else {\n",
774 " this.send_message('toolbar_button', { name: name });\n",
775 " }\n",
776 "};\n",
777 "\n",
778 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
779 " this.message.textContent = tooltip;\n",
780 "};\n",
781 "\n",
782 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
783 "// prettier-ignore\n",
784 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
785 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
786 "\n",
787 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
788 "\n",
789 "mpl.default_extension = \"png\";/* global mpl */\n",
790 "\n",
791 "var comm_websocket_adapter = function (comm) {\n",
792 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
793 " // object with the appropriate methods. Currently this is a non binary\n",
794 " // socket, so there is still some room for performance tuning.\n",
795 " var ws = {};\n",
796 "\n",
797 " ws.close = function () {\n",
798 " comm.close();\n",
799 " };\n",
800 " ws.send = function (m) {\n",
801 " //console.log('sending', m);\n",
802 " comm.send(m);\n",
803 " };\n",
804 " // Register the callback with on_msg.\n",
805 " comm.on_msg(function (msg) {\n",
806 " //console.log('receiving', msg['content']['data'], msg);\n",
807 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
808 " ws.onmessage(msg['content']['data']);\n",
809 " });\n",
810 " return ws;\n",
811 "};\n",
812 "\n",
813 "mpl.mpl_figure_comm = function (comm, msg) {\n",
814 " // This is the function which gets called when the mpl process\n",
815 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
816 "\n",
817 " var id = msg.content.data.id;\n",
818 " // Get hold of the div created by the display call when the Comm\n",
819 " // socket was opened in Python.\n",
820 " var element = document.getElementById(id);\n",
821 " var ws_proxy = comm_websocket_adapter(comm);\n",
822 "\n",
823 " function ondownload(figure, _format) {\n",
824 " window.open(figure.canvas.toDataURL());\n",
825 " }\n",
826 "\n",
827 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
828 "\n",
829 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
830 " // web socket which is closed, not our websocket->open comm proxy.\n",
831 " ws_proxy.onopen();\n",
832 "\n",
833 " fig.parent_element = element;\n",
834 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
835 " if (!fig.cell_info) {\n",
836 " console.error('Failed to find cell for figure', id, fig);\n",
837 " return;\n",
838 " }\n",
839 " fig.cell_info[0].output_area.element.on(\n",
840 " 'cleared',\n",
841 " { fig: fig },\n",
842 " fig._remove_fig_handler\n",
843 " );\n",
844 "};\n",
845 "\n",
846 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
847 " var width = fig.canvas.width / fig.ratio;\n",
848 " fig.cell_info[0].output_area.element.off(\n",
849 " 'cleared',\n",
850 " fig._remove_fig_handler\n",
851 " );\n",
852 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
853 "\n",
854 " // Update the output cell to use the data from the current canvas.\n",
855 " fig.push_to_output();\n",
856 " var dataURL = fig.canvas.toDataURL();\n",
857 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
858 " // the notebook keyboard shortcuts fail.\n",
859 " IPython.keyboard_manager.enable();\n",
860 " fig.parent_element.innerHTML =\n",
861 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
862 " fig.close_ws(fig, msg);\n",
863 "};\n",
864 "\n",
865 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
866 " fig.send_message('closing', msg);\n",
867 " // fig.ws.close()\n",
868 "};\n",
869 "\n",
870 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
871 " // Turn the data on the canvas into data in the output cell.\n",
872 " var width = this.canvas.width / this.ratio;\n",
873 " var dataURL = this.canvas.toDataURL();\n",
874 " this.cell_info[1]['text/html'] =\n",
875 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
876 "};\n",
877 "\n",
878 "mpl.figure.prototype.updated_canvas_event = function () {\n",
879 " // Tell IPython that the notebook contents must change.\n",
880 " IPython.notebook.set_dirty(true);\n",
881 " this.send_message('ack', {});\n",
882 " var fig = this;\n",
883 " // Wait a second, then push the new image to the DOM so\n",
884 " // that it is saved nicely (might be nice to debounce this).\n",
885 " setTimeout(function () {\n",
886 " fig.push_to_output();\n",
887 " }, 1000);\n",
888 "};\n",
889 "\n",
890 "mpl.figure.prototype._init_toolbar = function () {\n",
891 " var fig = this;\n",
892 "\n",
893 " var toolbar = document.createElement('div');\n",
894 " toolbar.classList = 'btn-toolbar';\n",
895 " this.root.appendChild(toolbar);\n",
896 "\n",
897 " function on_click_closure(name) {\n",
898 " return function (_event) {\n",
899 " return fig.toolbar_button_onclick(name);\n",
900 " };\n",
901 " }\n",
902 "\n",
903 " function on_mouseover_closure(tooltip) {\n",
904 " return function (event) {\n",
905 " if (!event.currentTarget.disabled) {\n",
906 " return fig.toolbar_button_onmouseover(tooltip);\n",
907 " }\n",
908 " };\n",
909 " }\n",
910 "\n",
911 " fig.buttons = {};\n",
912 " var buttonGroup = document.createElement('div');\n",
913 " buttonGroup.classList = 'btn-group';\n",
914 " var button;\n",
915 " for (var toolbar_ind in mpl.toolbar_items) {\n",
916 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
917 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
918 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
919 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
920 "\n",
921 " if (!name) {\n",
922 " /* Instead of a spacer, we start a new button group. */\n",
923 " if (buttonGroup.hasChildNodes()) {\n",
924 " toolbar.appendChild(buttonGroup);\n",
925 " }\n",
926 " buttonGroup = document.createElement('div');\n",
927 " buttonGroup.classList = 'btn-group';\n",
928 " continue;\n",
929 " }\n",
930 "\n",
931 " button = fig.buttons[name] = document.createElement('button');\n",
932 " button.classList = 'btn btn-default';\n",
933 " button.href = '#';\n",
934 " button.title = name;\n",
935 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
936 " button.addEventListener('click', on_click_closure(method_name));\n",
937 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
938 " buttonGroup.appendChild(button);\n",
939 " }\n",
940 "\n",
941 " if (buttonGroup.hasChildNodes()) {\n",
942 " toolbar.appendChild(buttonGroup);\n",
943 " }\n",
944 "\n",
945 " // Add the status bar.\n",
946 " var status_bar = document.createElement('span');\n",
947 " status_bar.classList = 'mpl-message pull-right';\n",
948 " toolbar.appendChild(status_bar);\n",
949 " this.message = status_bar;\n",
950 "\n",
951 " // Add the close button to the window.\n",
952 " var buttongrp = document.createElement('div');\n",
953 " buttongrp.classList = 'btn-group inline pull-right';\n",
954 " button = document.createElement('button');\n",
955 " button.classList = 'btn btn-mini btn-primary';\n",
956 " button.href = '#';\n",
957 " button.title = 'Stop Interaction';\n",
958 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
959 " button.addEventListener('click', function (_evt) {\n",
960 " fig.handle_close(fig, {});\n",
961 " });\n",
962 " button.addEventListener(\n",
963 " 'mouseover',\n",
964 " on_mouseover_closure('Stop Interaction')\n",
965 " );\n",
966 " buttongrp.appendChild(button);\n",
967 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
968 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
969 "};\n",
970 "\n",
971 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
972 " var fig = event.data.fig;\n",
973 " if (event.target !== this) {\n",
974 " // Ignore bubbled events from children.\n",
975 " return;\n",
976 " }\n",
977 " fig.close_ws(fig, {});\n",
978 "};\n",
979 "\n",
980 "mpl.figure.prototype._root_extra_style = function (el) {\n",
981 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
982 "};\n",
983 "\n",
984 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
985 " // this is important to make the div 'focusable\n",
986 " el.setAttribute('tabindex', 0);\n",
987 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
988 " // off when our div gets focus\n",
989 "\n",
990 " // location in version 3\n",
991 " if (IPython.notebook.keyboard_manager) {\n",
992 " IPython.notebook.keyboard_manager.register_events(el);\n",
993 " } else {\n",
994 " // location in version 2\n",
995 " IPython.keyboard_manager.register_events(el);\n",
996 " }\n",
997 "};\n",
998 "\n",
999 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
1000 " var manager = IPython.notebook.keyboard_manager;\n",
1001 " if (!manager) {\n",
1002 " manager = IPython.keyboard_manager;\n",
1003 " }\n",
1004 "\n",
1005 " // Check for shift+enter\n",
1006 " if (event.shiftKey && event.which === 13) {\n",
1007 " this.canvas_div.blur();\n",
1008 " // select the cell after this one\n",
1009 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
1010 " IPython.notebook.select(index + 1);\n",
1011 " }\n",
1012 "};\n",
1013 "\n",
1014 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
1015 " fig.ondownload(fig, null);\n",
1016 "};\n",
1017 "\n",
1018 "mpl.find_output_cell = function (html_output) {\n",
1019 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
1020 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
1021 " // IPython event is triggered only after the cells have been serialised, which for\n",
1022 " // our purposes (turning an active figure into a static one), is too late.\n",
1023 " var cells = IPython.notebook.get_cells();\n",
1024 " var ncells = cells.length;\n",
1025 " for (var i = 0; i < ncells; i++) {\n",
1026 " var cell = cells[i];\n",
1027 " if (cell.cell_type === 'code') {\n",
1028 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
1029 " var data = cell.output_area.outputs[j];\n",
1030 " if (data.data) {\n",
1031 " // IPython >= 3 moved mimebundle to data attribute of output\n",
1032 " data = data.data;\n",
1033 " }\n",
1034 " if (data['text/html'] === html_output) {\n",
1035 " return [cell, data, j];\n",
1036 " }\n",
1037 " }\n",
1038 " }\n",
1039 " }\n",
1040 "};\n",
1041 "\n",
1042 "// Register the function which deals with the matplotlib target/channel.\n",
1043 "// The kernel may be null if the page has been refreshed.\n",
1044 "if (IPython.notebook.kernel !== null) {\n",
1045 " IPython.notebook.kernel.comm_manager.register_target(\n",
1046 " 'matplotlib',\n",
1047 " mpl.mpl_figure_comm\n",
1048 " );\n",
1049 "}\n"
1050 ],
1051 "text/plain": [
1052 "<IPython.core.display.Javascript object>"
1053 ]
1054 },
1055 "metadata": {},
1056 "output_type": "display_data"
1057 },
1058 {
1059 "data": {
1060 "text/html": [
1061 "<div id='beb48092-c450-45b4-bd2a-8f24de3b03ac'></div>"
1062 ],
1063 "text/plain": [
1064 "<IPython.core.display.HTML object>"
1065 ]
1066 },
1067 "metadata": {},
1068 "output_type": "display_data"
1069 },
1070 {
1071 "data": {
1072 "application/javascript": [
1073 "/* Put everything inside the global mpl namespace */\n",
1074 "/* global mpl */\n",
1075 "window.mpl = {};\n",
1076 "\n",
1077 "mpl.get_websocket_type = function () {\n",
1078 " if (typeof WebSocket !== 'undefined') {\n",
1079 " return WebSocket;\n",
1080 " } else if (typeof MozWebSocket !== 'undefined') {\n",
1081 " return MozWebSocket;\n",
1082 " } else {\n",
1083 " alert(\n",
1084 " 'Your browser does not have WebSocket support. ' +\n",
1085 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
1086 " 'Firefox 4 and 5 are also supported but you ' +\n",
1087 " 'have to enable WebSockets in about:config.'\n",
1088 " );\n",
1089 " }\n",
1090 "};\n",
1091 "\n",
1092 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
1093 " this.id = figure_id;\n",
1094 "\n",
1095 " this.ws = websocket;\n",
1096 "\n",
1097 " this.supports_binary = this.ws.binaryType !== undefined;\n",
1098 "\n",
1099 " if (!this.supports_binary) {\n",
1100 " var warnings = document.getElementById('mpl-warnings');\n",
1101 " if (warnings) {\n",
1102 " warnings.style.display = 'block';\n",
1103 " warnings.textContent =\n",
1104 " 'This browser does not support binary websocket messages. ' +\n",
1105 " 'Performance may be slow.';\n",
1106 " }\n",
1107 " }\n",
1108 "\n",
1109 " this.imageObj = new Image();\n",
1110 "\n",
1111 " this.context = undefined;\n",
1112 " this.message = undefined;\n",
1113 " this.canvas = undefined;\n",
1114 " this.rubberband_canvas = undefined;\n",
1115 " this.rubberband_context = undefined;\n",
1116 " this.format_dropdown = undefined;\n",
1117 "\n",
1118 " this.image_mode = 'full';\n",
1119 "\n",
1120 " this.root = document.createElement('div');\n",
1121 " this.root.setAttribute('style', 'display: inline-block');\n",
1122 " this._root_extra_style(this.root);\n",
1123 "\n",
1124 " parent_element.appendChild(this.root);\n",
1125 "\n",
1126 " this._init_header(this);\n",
1127 " this._init_canvas(this);\n",
1128 " this._init_toolbar(this);\n",
1129 "\n",
1130 " var fig = this;\n",
1131 "\n",
1132 " this.waiting = false;\n",
1133 "\n",
1134 " this.ws.onopen = function () {\n",
1135 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
1136 " fig.send_message('send_image_mode', {});\n",
1137 " if (fig.ratio !== 1) {\n",
1138 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
1139 " }\n",
1140 " fig.send_message('refresh', {});\n",
1141 " };\n",
1142 "\n",
1143 " this.imageObj.onload = function () {\n",
1144 " if (fig.image_mode === 'full') {\n",
1145 " // Full images could contain transparency (where diff images\n",
1146 " // almost always do), so we need to clear the canvas so that\n",
1147 " // there is no ghosting.\n",
1148 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
1149 " }\n",
1150 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
1151 " };\n",
1152 "\n",
1153 " this.imageObj.onunload = function () {\n",
1154 " fig.ws.close();\n",
1155 " };\n",
1156 "\n",
1157 " this.ws.onmessage = this._make_on_message_function(this);\n",
1158 "\n",
1159 " this.ondownload = ondownload;\n",
1160 "};\n",
1161 "\n",
1162 "mpl.figure.prototype._init_header = function () {\n",
1163 " var titlebar = document.createElement('div');\n",
1164 " titlebar.classList =\n",
1165 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
1166 " var titletext = document.createElement('div');\n",
1167 " titletext.classList = 'ui-dialog-title';\n",
1168 " titletext.setAttribute(\n",
1169 " 'style',\n",
1170 " 'width: 100%; text-align: center; padding: 3px;'\n",
1171 " );\n",
1172 " titlebar.appendChild(titletext);\n",
1173 " this.root.appendChild(titlebar);\n",
1174 " this.header = titletext;\n",
1175 "};\n",
1176 "\n",
1177 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
1178 "\n",
1179 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
1180 "\n",
1181 "mpl.figure.prototype._init_canvas = function () {\n",
1182 " var fig = this;\n",
1183 "\n",
1184 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
1185 " canvas_div.setAttribute(\n",
1186 " 'style',\n",
1187 " 'border: 1px solid #ddd;' +\n",
1188 " 'box-sizing: content-box;' +\n",
1189 " 'clear: both;' +\n",
1190 " 'min-height: 1px;' +\n",
1191 " 'min-width: 1px;' +\n",
1192 " 'outline: 0;' +\n",
1193 " 'overflow: hidden;' +\n",
1194 " 'position: relative;' +\n",
1195 " 'resize: both;'\n",
1196 " );\n",
1197 "\n",
1198 " function on_keyboard_event_closure(name) {\n",
1199 " return function (event) {\n",
1200 " return fig.key_event(event, name);\n",
1201 " };\n",
1202 " }\n",
1203 "\n",
1204 " canvas_div.addEventListener(\n",
1205 " 'keydown',\n",
1206 " on_keyboard_event_closure('key_press')\n",
1207 " );\n",
1208 " canvas_div.addEventListener(\n",
1209 " 'keyup',\n",
1210 " on_keyboard_event_closure('key_release')\n",
1211 " );\n",
1212 "\n",
1213 " this._canvas_extra_style(canvas_div);\n",
1214 " this.root.appendChild(canvas_div);\n",
1215 "\n",
1216 " var canvas = (this.canvas = document.createElement('canvas'));\n",
1217 " canvas.classList.add('mpl-canvas');\n",
1218 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
1219 "\n",
1220 " this.context = canvas.getContext('2d');\n",
1221 "\n",
1222 " var backingStore =\n",
1223 " this.context.backingStorePixelRatio ||\n",
1224 " this.context.webkitBackingStorePixelRatio ||\n",
1225 " this.context.mozBackingStorePixelRatio ||\n",
1226 " this.context.msBackingStorePixelRatio ||\n",
1227 " this.context.oBackingStorePixelRatio ||\n",
1228 " this.context.backingStorePixelRatio ||\n",
1229 " 1;\n",
1230 "\n",
1231 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
1232 "\n",
1233 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
1234 " 'canvas'\n",
1235 " ));\n",
1236 " rubberband_canvas.setAttribute(\n",
1237 " 'style',\n",
1238 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
1239 " );\n",
1240 "\n",
1241 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
1242 " if (this.ResizeObserver === undefined) {\n",
1243 " if (window.ResizeObserver !== undefined) {\n",
1244 " this.ResizeObserver = window.ResizeObserver;\n",
1245 " } else {\n",
1246 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
1247 " this.ResizeObserver = obs.ResizeObserver;\n",
1248 " }\n",
1249 " }\n",
1250 "\n",
1251 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
1252 " var nentries = entries.length;\n",
1253 " for (var i = 0; i < nentries; i++) {\n",
1254 " var entry = entries[i];\n",
1255 " var width, height;\n",
1256 " if (entry.contentBoxSize) {\n",
1257 " if (entry.contentBoxSize instanceof Array) {\n",
1258 " // Chrome 84 implements new version of spec.\n",
1259 " width = entry.contentBoxSize[0].inlineSize;\n",
1260 " height = entry.contentBoxSize[0].blockSize;\n",
1261 " } else {\n",
1262 " // Firefox implements old version of spec.\n",
1263 " width = entry.contentBoxSize.inlineSize;\n",
1264 " height = entry.contentBoxSize.blockSize;\n",
1265 " }\n",
1266 " } else {\n",
1267 " // Chrome <84 implements even older version of spec.\n",
1268 " width = entry.contentRect.width;\n",
1269 " height = entry.contentRect.height;\n",
1270 " }\n",
1271 "\n",
1272 " // Keep the size of the canvas and rubber band canvas in sync with\n",
1273 " // the canvas container.\n",
1274 " if (entry.devicePixelContentBoxSize) {\n",
1275 " // Chrome 84 implements new version of spec.\n",
1276 " canvas.setAttribute(\n",
1277 " 'width',\n",
1278 " entry.devicePixelContentBoxSize[0].inlineSize\n",
1279 " );\n",
1280 " canvas.setAttribute(\n",
1281 " 'height',\n",
1282 " entry.devicePixelContentBoxSize[0].blockSize\n",
1283 " );\n",
1284 " } else {\n",
1285 " canvas.setAttribute('width', width * fig.ratio);\n",
1286 " canvas.setAttribute('height', height * fig.ratio);\n",
1287 " }\n",
1288 " canvas.setAttribute(\n",
1289 " 'style',\n",
1290 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
1291 " );\n",
1292 "\n",
1293 " rubberband_canvas.setAttribute('width', width);\n",
1294 " rubberband_canvas.setAttribute('height', height);\n",
1295 "\n",
1296 " // And update the size in Python. We ignore the initial 0/0 size\n",
1297 " // that occurs as the element is placed into the DOM, which should\n",
1298 " // otherwise not happen due to the minimum size styling.\n",
1299 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
1300 " fig.request_resize(width, height);\n",
1301 " }\n",
1302 " }\n",
1303 " });\n",
1304 " this.resizeObserverInstance.observe(canvas_div);\n",
1305 "\n",
1306 " function on_mouse_event_closure(name) {\n",
1307 " return function (event) {\n",
1308 " return fig.mouse_event(event, name);\n",
1309 " };\n",
1310 " }\n",
1311 "\n",
1312 " rubberband_canvas.addEventListener(\n",
1313 " 'mousedown',\n",
1314 " on_mouse_event_closure('button_press')\n",
1315 " );\n",
1316 " rubberband_canvas.addEventListener(\n",
1317 " 'mouseup',\n",
1318 " on_mouse_event_closure('button_release')\n",
1319 " );\n",
1320 " // Throttle sequential mouse events to 1 every 20ms.\n",
1321 " rubberband_canvas.addEventListener(\n",
1322 " 'mousemove',\n",
1323 " on_mouse_event_closure('motion_notify')\n",
1324 " );\n",
1325 "\n",
1326 " rubberband_canvas.addEventListener(\n",
1327 " 'mouseenter',\n",
1328 " on_mouse_event_closure('figure_enter')\n",
1329 " );\n",
1330 " rubberband_canvas.addEventListener(\n",
1331 " 'mouseleave',\n",
1332 " on_mouse_event_closure('figure_leave')\n",
1333 " );\n",
1334 "\n",
1335 " canvas_div.addEventListener('wheel', function (event) {\n",
1336 " if (event.deltaY < 0) {\n",
1337 " event.step = 1;\n",
1338 " } else {\n",
1339 " event.step = -1;\n",
1340 " }\n",
1341 " on_mouse_event_closure('scroll')(event);\n",
1342 " });\n",
1343 "\n",
1344 " canvas_div.appendChild(canvas);\n",
1345 " canvas_div.appendChild(rubberband_canvas);\n",
1346 "\n",
1347 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
1348 " this.rubberband_context.strokeStyle = '#000000';\n",
1349 "\n",
1350 " this._resize_canvas = function (width, height, forward) {\n",
1351 " if (forward) {\n",
1352 " canvas_div.style.width = width + 'px';\n",
1353 " canvas_div.style.height = height + 'px';\n",
1354 " }\n",
1355 " };\n",
1356 "\n",
1357 " // Disable right mouse context menu.\n",
1358 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
1359 " event.preventDefault();\n",
1360 " return false;\n",
1361 " });\n",
1362 "\n",
1363 " function set_focus() {\n",
1364 " canvas.focus();\n",
1365 " canvas_div.focus();\n",
1366 " }\n",
1367 "\n",
1368 " window.setTimeout(set_focus, 100);\n",
1369 "};\n",
1370 "\n",
1371 "mpl.figure.prototype._init_toolbar = function () {\n",
1372 " var fig = this;\n",
1373 "\n",
1374 " var toolbar = document.createElement('div');\n",
1375 " toolbar.classList = 'mpl-toolbar';\n",
1376 " this.root.appendChild(toolbar);\n",
1377 "\n",
1378 " function on_click_closure(name) {\n",
1379 " return function (_event) {\n",
1380 " return fig.toolbar_button_onclick(name);\n",
1381 " };\n",
1382 " }\n",
1383 "\n",
1384 " function on_mouseover_closure(tooltip) {\n",
1385 " return function (event) {\n",
1386 " if (!event.currentTarget.disabled) {\n",
1387 " return fig.toolbar_button_onmouseover(tooltip);\n",
1388 " }\n",
1389 " };\n",
1390 " }\n",
1391 "\n",
1392 " fig.buttons = {};\n",
1393 " var buttonGroup = document.createElement('div');\n",
1394 " buttonGroup.classList = 'mpl-button-group';\n",
1395 " for (var toolbar_ind in mpl.toolbar_items) {\n",
1396 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
1397 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
1398 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
1399 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
1400 "\n",
1401 " if (!name) {\n",
1402 " /* Instead of a spacer, we start a new button group. */\n",
1403 " if (buttonGroup.hasChildNodes()) {\n",
1404 " toolbar.appendChild(buttonGroup);\n",
1405 " }\n",
1406 " buttonGroup = document.createElement('div');\n",
1407 " buttonGroup.classList = 'mpl-button-group';\n",
1408 " continue;\n",
1409 " }\n",
1410 "\n",
1411 " var button = (fig.buttons[name] = document.createElement('button'));\n",
1412 " button.classList = 'mpl-widget';\n",
1413 " button.setAttribute('role', 'button');\n",
1414 " button.setAttribute('aria-disabled', 'false');\n",
1415 " button.addEventListener('click', on_click_closure(method_name));\n",
1416 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
1417 "\n",
1418 " var icon_img = document.createElement('img');\n",
1419 " icon_img.src = '_images/' + image + '.png';\n",
1420 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
1421 " icon_img.alt = tooltip;\n",
1422 " button.appendChild(icon_img);\n",
1423 "\n",
1424 " buttonGroup.appendChild(button);\n",
1425 " }\n",
1426 "\n",
1427 " if (buttonGroup.hasChildNodes()) {\n",
1428 " toolbar.appendChild(buttonGroup);\n",
1429 " }\n",
1430 "\n",
1431 " var fmt_picker = document.createElement('select');\n",
1432 " fmt_picker.classList = 'mpl-widget';\n",
1433 " toolbar.appendChild(fmt_picker);\n",
1434 " this.format_dropdown = fmt_picker;\n",
1435 "\n",
1436 " for (var ind in mpl.extensions) {\n",
1437 " var fmt = mpl.extensions[ind];\n",
1438 " var option = document.createElement('option');\n",
1439 " option.selected = fmt === mpl.default_extension;\n",
1440 " option.innerHTML = fmt;\n",
1441 " fmt_picker.appendChild(option);\n",
1442 " }\n",
1443 "\n",
1444 " var status_bar = document.createElement('span');\n",
1445 " status_bar.classList = 'mpl-message';\n",
1446 " toolbar.appendChild(status_bar);\n",
1447 " this.message = status_bar;\n",
1448 "};\n",
1449 "\n",
1450 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
1451 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
1452 " // which will in turn request a refresh of the image.\n",
1453 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
1454 "};\n",
1455 "\n",
1456 "mpl.figure.prototype.send_message = function (type, properties) {\n",
1457 " properties['type'] = type;\n",
1458 " properties['figure_id'] = this.id;\n",
1459 " this.ws.send(JSON.stringify(properties));\n",
1460 "};\n",
1461 "\n",
1462 "mpl.figure.prototype.send_draw_message = function () {\n",
1463 " if (!this.waiting) {\n",
1464 " this.waiting = true;\n",
1465 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
1466 " }\n",
1467 "};\n",
1468 "\n",
1469 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
1470 " var format_dropdown = fig.format_dropdown;\n",
1471 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
1472 " fig.ondownload(fig, format);\n",
1473 "};\n",
1474 "\n",
1475 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
1476 " var size = msg['size'];\n",
1477 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
1478 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
1479 " fig.send_message('refresh', {});\n",
1480 " }\n",
1481 "};\n",
1482 "\n",
1483 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
1484 " var x0 = msg['x0'] / fig.ratio;\n",
1485 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
1486 " var x1 = msg['x1'] / fig.ratio;\n",
1487 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
1488 " x0 = Math.floor(x0) + 0.5;\n",
1489 " y0 = Math.floor(y0) + 0.5;\n",
1490 " x1 = Math.floor(x1) + 0.5;\n",
1491 " y1 = Math.floor(y1) + 0.5;\n",
1492 " var min_x = Math.min(x0, x1);\n",
1493 " var min_y = Math.min(y0, y1);\n",
1494 " var width = Math.abs(x1 - x0);\n",
1495 " var height = Math.abs(y1 - y0);\n",
1496 "\n",
1497 " fig.rubberband_context.clearRect(\n",
1498 " 0,\n",
1499 " 0,\n",
1500 " fig.canvas.width / fig.ratio,\n",
1501 " fig.canvas.height / fig.ratio\n",
1502 " );\n",
1503 "\n",
1504 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
1505 "};\n",
1506 "\n",
1507 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
1508 " // Updates the figure title.\n",
1509 " fig.header.textContent = msg['label'];\n",
1510 "};\n",
1511 "\n",
1512 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
1513 " var cursor = msg['cursor'];\n",
1514 " switch (cursor) {\n",
1515 " case 0:\n",
1516 " cursor = 'pointer';\n",
1517 " break;\n",
1518 " case 1:\n",
1519 " cursor = 'default';\n",
1520 " break;\n",
1521 " case 2:\n",
1522 " cursor = 'crosshair';\n",
1523 " break;\n",
1524 " case 3:\n",
1525 " cursor = 'move';\n",
1526 " break;\n",
1527 " }\n",
1528 " fig.rubberband_canvas.style.cursor = cursor;\n",
1529 "};\n",
1530 "\n",
1531 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
1532 " fig.message.textContent = msg['message'];\n",
1533 "};\n",
1534 "\n",
1535 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
1536 " // Request the server to send over a new figure.\n",
1537 " fig.send_draw_message();\n",
1538 "};\n",
1539 "\n",
1540 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
1541 " fig.image_mode = msg['mode'];\n",
1542 "};\n",
1543 "\n",
1544 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
1545 " for (var key in msg) {\n",
1546 " if (!(key in fig.buttons)) {\n",
1547 " continue;\n",
1548 " }\n",
1549 " fig.buttons[key].disabled = !msg[key];\n",
1550 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
1551 " }\n",
1552 "};\n",
1553 "\n",
1554 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
1555 " if (msg['mode'] === 'PAN') {\n",
1556 " fig.buttons['Pan'].classList.add('active');\n",
1557 " fig.buttons['Zoom'].classList.remove('active');\n",
1558 " } else if (msg['mode'] === 'ZOOM') {\n",
1559 " fig.buttons['Pan'].classList.remove('active');\n",
1560 " fig.buttons['Zoom'].classList.add('active');\n",
1561 " } else {\n",
1562 " fig.buttons['Pan'].classList.remove('active');\n",
1563 " fig.buttons['Zoom'].classList.remove('active');\n",
1564 " }\n",
1565 "};\n",
1566 "\n",
1567 "mpl.figure.prototype.updated_canvas_event = function () {\n",
1568 " // Called whenever the canvas gets updated.\n",
1569 " this.send_message('ack', {});\n",
1570 "};\n",
1571 "\n",
1572 "// A function to construct a web socket function for onmessage handling.\n",
1573 "// Called in the figure constructor.\n",
1574 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
1575 " return function socket_on_message(evt) {\n",
1576 " if (evt.data instanceof Blob) {\n",
1577 " /* FIXME: We get \"Resource interpreted as Image but\n",
1578 " * transferred with MIME type text/plain:\" errors on\n",
1579 " * Chrome. But how to set the MIME type? It doesn't seem\n",
1580 " * to be part of the websocket stream */\n",
1581 " evt.data.type = 'image/png';\n",
1582 "\n",
1583 " /* Free the memory for the previous frames */\n",
1584 " if (fig.imageObj.src) {\n",
1585 " (window.URL || window.webkitURL).revokeObjectURL(\n",
1586 " fig.imageObj.src\n",
1587 " );\n",
1588 " }\n",
1589 "\n",
1590 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
1591 " evt.data\n",
1592 " );\n",
1593 " fig.updated_canvas_event();\n",
1594 " fig.waiting = false;\n",
1595 " return;\n",
1596 " } else if (\n",
1597 " typeof evt.data === 'string' &&\n",
1598 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
1599 " ) {\n",
1600 " fig.imageObj.src = evt.data;\n",
1601 " fig.updated_canvas_event();\n",
1602 " fig.waiting = false;\n",
1603 " return;\n",
1604 " }\n",
1605 "\n",
1606 " var msg = JSON.parse(evt.data);\n",
1607 " var msg_type = msg['type'];\n",
1608 "\n",
1609 " // Call the \"handle_{type}\" callback, which takes\n",
1610 " // the figure and JSON message as its only arguments.\n",
1611 " try {\n",
1612 " var callback = fig['handle_' + msg_type];\n",
1613 " } catch (e) {\n",
1614 " console.log(\n",
1615 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
1616 " msg\n",
1617 " );\n",
1618 " return;\n",
1619 " }\n",
1620 "\n",
1621 " if (callback) {\n",
1622 " try {\n",
1623 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
1624 " callback(fig, msg);\n",
1625 " } catch (e) {\n",
1626 " console.log(\n",
1627 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
1628 " e,\n",
1629 " e.stack,\n",
1630 " msg\n",
1631 " );\n",
1632 " }\n",
1633 " }\n",
1634 " };\n",
1635 "};\n",
1636 "\n",
1637 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
1638 "mpl.findpos = function (e) {\n",
1639 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
1640 " var targ;\n",
1641 " if (!e) {\n",
1642 " e = window.event;\n",
1643 " }\n",
1644 " if (e.target) {\n",
1645 " targ = e.target;\n",
1646 " } else if (e.srcElement) {\n",
1647 " targ = e.srcElement;\n",
1648 " }\n",
1649 " if (targ.nodeType === 3) {\n",
1650 " // defeat Safari bug\n",
1651 " targ = targ.parentNode;\n",
1652 " }\n",
1653 "\n",
1654 " // pageX,Y are the mouse positions relative to the document\n",
1655 " var boundingRect = targ.getBoundingClientRect();\n",
1656 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
1657 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
1658 "\n",
1659 " return { x: x, y: y };\n",
1660 "};\n",
1661 "\n",
1662 "/*\n",
1663 " * return a copy of an object with only non-object keys\n",
1664 " * we need this to avoid circular references\n",
1665 " * http://stackoverflow.com/a/24161582/3208463\n",
1666 " */\n",
1667 "function simpleKeys(original) {\n",
1668 " return Object.keys(original).reduce(function (obj, key) {\n",
1669 " if (typeof original[key] !== 'object') {\n",
1670 " obj[key] = original[key];\n",
1671 " }\n",
1672 " return obj;\n",
1673 " }, {});\n",
1674 "}\n",
1675 "\n",
1676 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
1677 " var canvas_pos = mpl.findpos(event);\n",
1678 "\n",
1679 " if (name === 'button_press') {\n",
1680 " this.canvas.focus();\n",
1681 " this.canvas_div.focus();\n",
1682 " }\n",
1683 "\n",
1684 " var x = canvas_pos.x * this.ratio;\n",
1685 " var y = canvas_pos.y * this.ratio;\n",
1686 "\n",
1687 " this.send_message(name, {\n",
1688 " x: x,\n",
1689 " y: y,\n",
1690 " button: event.button,\n",
1691 " step: event.step,\n",
1692 " guiEvent: simpleKeys(event),\n",
1693 " });\n",
1694 "\n",
1695 " /* This prevents the web browser from automatically changing to\n",
1696 " * the text insertion cursor when the button is pressed. We want\n",
1697 " * to control all of the cursor setting manually through the\n",
1698 " * 'cursor' event from matplotlib */\n",
1699 " event.preventDefault();\n",
1700 " return false;\n",
1701 "};\n",
1702 "\n",
1703 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
1704 " // Handle any extra behaviour associated with a key event\n",
1705 "};\n",
1706 "\n",
1707 "mpl.figure.prototype.key_event = function (event, name) {\n",
1708 " // Prevent repeat events\n",
1709 " if (name === 'key_press') {\n",
1710 " if (event.which === this._key) {\n",
1711 " return;\n",
1712 " } else {\n",
1713 " this._key = event.which;\n",
1714 " }\n",
1715 " }\n",
1716 " if (name === 'key_release') {\n",
1717 " this._key = null;\n",
1718 " }\n",
1719 "\n",
1720 " var value = '';\n",
1721 " if (event.ctrlKey && event.which !== 17) {\n",
1722 " value += 'ctrl+';\n",
1723 " }\n",
1724 " if (event.altKey && event.which !== 18) {\n",
1725 " value += 'alt+';\n",
1726 " }\n",
1727 " if (event.shiftKey && event.which !== 16) {\n",
1728 " value += 'shift+';\n",
1729 " }\n",
1730 "\n",
1731 " value += 'k';\n",
1732 " value += event.which.toString();\n",
1733 "\n",
1734 " this._key_event_extra(event, name);\n",
1735 "\n",
1736 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
1737 " return false;\n",
1738 "};\n",
1739 "\n",
1740 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
1741 " if (name === 'download') {\n",
1742 " this.handle_save(this, null);\n",
1743 " } else {\n",
1744 " this.send_message('toolbar_button', { name: name });\n",
1745 " }\n",
1746 "};\n",
1747 "\n",
1748 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
1749 " this.message.textContent = tooltip;\n",
1750 "};\n",
1751 "\n",
1752 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
1753 "// prettier-ignore\n",
1754 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
1755 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
1756 "\n",
1757 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
1758 "\n",
1759 "mpl.default_extension = \"png\";/* global mpl */\n",
1760 "\n",
1761 "var comm_websocket_adapter = function (comm) {\n",
1762 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
1763 " // object with the appropriate methods. Currently this is a non binary\n",
1764 " // socket, so there is still some room for performance tuning.\n",
1765 " var ws = {};\n",
1766 "\n",
1767 " ws.close = function () {\n",
1768 " comm.close();\n",
1769 " };\n",
1770 " ws.send = function (m) {\n",
1771 " //console.log('sending', m);\n",
1772 " comm.send(m);\n",
1773 " };\n",
1774 " // Register the callback with on_msg.\n",
1775 " comm.on_msg(function (msg) {\n",
1776 " //console.log('receiving', msg['content']['data'], msg);\n",
1777 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
1778 " ws.onmessage(msg['content']['data']);\n",
1779 " });\n",
1780 " return ws;\n",
1781 "};\n",
1782 "\n",
1783 "mpl.mpl_figure_comm = function (comm, msg) {\n",
1784 " // This is the function which gets called when the mpl process\n",
1785 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
1786 "\n",
1787 " var id = msg.content.data.id;\n",
1788 " // Get hold of the div created by the display call when the Comm\n",
1789 " // socket was opened in Python.\n",
1790 " var element = document.getElementById(id);\n",
1791 " var ws_proxy = comm_websocket_adapter(comm);\n",
1792 "\n",
1793 " function ondownload(figure, _format) {\n",
1794 " window.open(figure.canvas.toDataURL());\n",
1795 " }\n",
1796 "\n",
1797 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
1798 "\n",
1799 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
1800 " // web socket which is closed, not our websocket->open comm proxy.\n",
1801 " ws_proxy.onopen();\n",
1802 "\n",
1803 " fig.parent_element = element;\n",
1804 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
1805 " if (!fig.cell_info) {\n",
1806 " console.error('Failed to find cell for figure', id, fig);\n",
1807 " return;\n",
1808 " }\n",
1809 " fig.cell_info[0].output_area.element.on(\n",
1810 " 'cleared',\n",
1811 " { fig: fig },\n",
1812 " fig._remove_fig_handler\n",
1813 " );\n",
1814 "};\n",
1815 "\n",
1816 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
1817 " var width = fig.canvas.width / fig.ratio;\n",
1818 " fig.cell_info[0].output_area.element.off(\n",
1819 " 'cleared',\n",
1820 " fig._remove_fig_handler\n",
1821 " );\n",
1822 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
1823 "\n",
1824 " // Update the output cell to use the data from the current canvas.\n",
1825 " fig.push_to_output();\n",
1826 " var dataURL = fig.canvas.toDataURL();\n",
1827 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
1828 " // the notebook keyboard shortcuts fail.\n",
1829 " IPython.keyboard_manager.enable();\n",
1830 " fig.parent_element.innerHTML =\n",
1831 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
1832 " fig.close_ws(fig, msg);\n",
1833 "};\n",
1834 "\n",
1835 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
1836 " fig.send_message('closing', msg);\n",
1837 " // fig.ws.close()\n",
1838 "};\n",
1839 "\n",
1840 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
1841 " // Turn the data on the canvas into data in the output cell.\n",
1842 " var width = this.canvas.width / this.ratio;\n",
1843 " var dataURL = this.canvas.toDataURL();\n",
1844 " this.cell_info[1]['text/html'] =\n",
1845 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
1846 "};\n",
1847 "\n",
1848 "mpl.figure.prototype.updated_canvas_event = function () {\n",
1849 " // Tell IPython that the notebook contents must change.\n",
1850 " IPython.notebook.set_dirty(true);\n",
1851 " this.send_message('ack', {});\n",
1852 " var fig = this;\n",
1853 " // Wait a second, then push the new image to the DOM so\n",
1854 " // that it is saved nicely (might be nice to debounce this).\n",
1855 " setTimeout(function () {\n",
1856 " fig.push_to_output();\n",
1857 " }, 1000);\n",
1858 "};\n",
1859 "\n",
1860 "mpl.figure.prototype._init_toolbar = function () {\n",
1861 " var fig = this;\n",
1862 "\n",
1863 " var toolbar = document.createElement('div');\n",
1864 " toolbar.classList = 'btn-toolbar';\n",
1865 " this.root.appendChild(toolbar);\n",
1866 "\n",
1867 " function on_click_closure(name) {\n",
1868 " return function (_event) {\n",
1869 " return fig.toolbar_button_onclick(name);\n",
1870 " };\n",
1871 " }\n",
1872 "\n",
1873 " function on_mouseover_closure(tooltip) {\n",
1874 " return function (event) {\n",
1875 " if (!event.currentTarget.disabled) {\n",
1876 " return fig.toolbar_button_onmouseover(tooltip);\n",
1877 " }\n",
1878 " };\n",
1879 " }\n",
1880 "\n",
1881 " fig.buttons = {};\n",
1882 " var buttonGroup = document.createElement('div');\n",
1883 " buttonGroup.classList = 'btn-group';\n",
1884 " var button;\n",
1885 " for (var toolbar_ind in mpl.toolbar_items) {\n",
1886 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
1887 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
1888 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
1889 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
1890 "\n",
1891 " if (!name) {\n",
1892 " /* Instead of a spacer, we start a new button group. */\n",
1893 " if (buttonGroup.hasChildNodes()) {\n",
1894 " toolbar.appendChild(buttonGroup);\n",
1895 " }\n",
1896 " buttonGroup = document.createElement('div');\n",
1897 " buttonGroup.classList = 'btn-group';\n",
1898 " continue;\n",
1899 " }\n",
1900 "\n",
1901 " button = fig.buttons[name] = document.createElement('button');\n",
1902 " button.classList = 'btn btn-default';\n",
1903 " button.href = '#';\n",
1904 " button.title = name;\n",
1905 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
1906 " button.addEventListener('click', on_click_closure(method_name));\n",
1907 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
1908 " buttonGroup.appendChild(button);\n",
1909 " }\n",
1910 "\n",
1911 " if (buttonGroup.hasChildNodes()) {\n",
1912 " toolbar.appendChild(buttonGroup);\n",
1913 " }\n",
1914 "\n",
1915 " // Add the status bar.\n",
1916 " var status_bar = document.createElement('span');\n",
1917 " status_bar.classList = 'mpl-message pull-right';\n",
1918 " toolbar.appendChild(status_bar);\n",
1919 " this.message = status_bar;\n",
1920 "\n",
1921 " // Add the close button to the window.\n",
1922 " var buttongrp = document.createElement('div');\n",
1923 " buttongrp.classList = 'btn-group inline pull-right';\n",
1924 " button = document.createElement('button');\n",
1925 " button.classList = 'btn btn-mini btn-primary';\n",
1926 " button.href = '#';\n",
1927 " button.title = 'Stop Interaction';\n",
1928 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
1929 " button.addEventListener('click', function (_evt) {\n",
1930 " fig.handle_close(fig, {});\n",
1931 " });\n",
1932 " button.addEventListener(\n",
1933 " 'mouseover',\n",
1934 " on_mouseover_closure('Stop Interaction')\n",
1935 " );\n",
1936 " buttongrp.appendChild(button);\n",
1937 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
1938 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
1939 "};\n",
1940 "\n",
1941 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
1942 " var fig = event.data.fig;\n",
1943 " if (event.target !== this) {\n",
1944 " // Ignore bubbled events from children.\n",
1945 " return;\n",
1946 " }\n",
1947 " fig.close_ws(fig, {});\n",
1948 "};\n",
1949 "\n",
1950 "mpl.figure.prototype._root_extra_style = function (el) {\n",
1951 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
1952 "};\n",
1953 "\n",
1954 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
1955 " // this is important to make the div 'focusable\n",
1956 " el.setAttribute('tabindex', 0);\n",
1957 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
1958 " // off when our div gets focus\n",
1959 "\n",
1960 " // location in version 3\n",
1961 " if (IPython.notebook.keyboard_manager) {\n",
1962 " IPython.notebook.keyboard_manager.register_events(el);\n",
1963 " } else {\n",
1964 " // location in version 2\n",
1965 " IPython.keyboard_manager.register_events(el);\n",
1966 " }\n",
1967 "};\n",
1968 "\n",
1969 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
1970 " var manager = IPython.notebook.keyboard_manager;\n",
1971 " if (!manager) {\n",
1972 " manager = IPython.keyboard_manager;\n",
1973 " }\n",
1974 "\n",
1975 " // Check for shift+enter\n",
1976 " if (event.shiftKey && event.which === 13) {\n",
1977 " this.canvas_div.blur();\n",
1978 " // select the cell after this one\n",
1979 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
1980 " IPython.notebook.select(index + 1);\n",
1981 " }\n",
1982 "};\n",
1983 "\n",
1984 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
1985 " fig.ondownload(fig, null);\n",
1986 "};\n",
1987 "\n",
1988 "mpl.find_output_cell = function (html_output) {\n",
1989 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
1990 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
1991 " // IPython event is triggered only after the cells have been serialised, which for\n",
1992 " // our purposes (turning an active figure into a static one), is too late.\n",
1993 " var cells = IPython.notebook.get_cells();\n",
1994 " var ncells = cells.length;\n",
1995 " for (var i = 0; i < ncells; i++) {\n",
1996 " var cell = cells[i];\n",
1997 " if (cell.cell_type === 'code') {\n",
1998 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
1999 " var data = cell.output_area.outputs[j];\n",
2000 " if (data.data) {\n",
2001 " // IPython >= 3 moved mimebundle to data attribute of output\n",
2002 " data = data.data;\n",
2003 " }\n",
2004 " if (data['text/html'] === html_output) {\n",
2005 " return [cell, data, j];\n",
2006 " }\n",
2007 " }\n",
2008 " }\n",
2009 " }\n",
2010 "};\n",
2011 "\n",
2012 "// Register the function which deals with the matplotlib target/channel.\n",
2013 "// The kernel may be null if the page has been refreshed.\n",
2014 "if (IPython.notebook.kernel !== null) {\n",
2015 " IPython.notebook.kernel.comm_manager.register_target(\n",
2016 " 'matplotlib',\n",
2017 " mpl.mpl_figure_comm\n",
2018 " );\n",
2019 "}\n"
2020 ],
2021 "text/plain": [
2022 "<IPython.core.display.Javascript object>"
2023 ]
2024 },
2025 "metadata": {},
2026 "output_type": "display_data"
2027 },
2028 {
2029 "data": {
2030 "text/html": [
2031 "<div id='bda3b66e-054c-478e-af62-f9177c939cee'></div>"
2032 ],
2033 "text/plain": [
2034 "<IPython.core.display.HTML object>"
2035 ]
2036 },
2037 "metadata": {},
2038 "output_type": "display_data"
2039 },
2040 {
2041 "data": {
2042 "application/javascript": [
2043 "/* Put everything inside the global mpl namespace */\n",
2044 "/* global mpl */\n",
2045 "window.mpl = {};\n",
2046 "\n",
2047 "mpl.get_websocket_type = function () {\n",
2048 " if (typeof WebSocket !== 'undefined') {\n",
2049 " return WebSocket;\n",
2050 " } else if (typeof MozWebSocket !== 'undefined') {\n",
2051 " return MozWebSocket;\n",
2052 " } else {\n",
2053 " alert(\n",
2054 " 'Your browser does not have WebSocket support. ' +\n",
2055 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
2056 " 'Firefox 4 and 5 are also supported but you ' +\n",
2057 " 'have to enable WebSockets in about:config.'\n",
2058 " );\n",
2059 " }\n",
2060 "};\n",
2061 "\n",
2062 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
2063 " this.id = figure_id;\n",
2064 "\n",
2065 " this.ws = websocket;\n",
2066 "\n",
2067 " this.supports_binary = this.ws.binaryType !== undefined;\n",
2068 "\n",
2069 " if (!this.supports_binary) {\n",
2070 " var warnings = document.getElementById('mpl-warnings');\n",
2071 " if (warnings) {\n",
2072 " warnings.style.display = 'block';\n",
2073 " warnings.textContent =\n",
2074 " 'This browser does not support binary websocket messages. ' +\n",
2075 " 'Performance may be slow.';\n",
2076 " }\n",
2077 " }\n",
2078 "\n",
2079 " this.imageObj = new Image();\n",
2080 "\n",
2081 " this.context = undefined;\n",
2082 " this.message = undefined;\n",
2083 " this.canvas = undefined;\n",
2084 " this.rubberband_canvas = undefined;\n",
2085 " this.rubberband_context = undefined;\n",
2086 " this.format_dropdown = undefined;\n",
2087 "\n",
2088 " this.image_mode = 'full';\n",
2089 "\n",
2090 " this.root = document.createElement('div');\n",
2091 " this.root.setAttribute('style', 'display: inline-block');\n",
2092 " this._root_extra_style(this.root);\n",
2093 "\n",
2094 " parent_element.appendChild(this.root);\n",
2095 "\n",
2096 " this._init_header(this);\n",
2097 " this._init_canvas(this);\n",
2098 " this._init_toolbar(this);\n",
2099 "\n",
2100 " var fig = this;\n",
2101 "\n",
2102 " this.waiting = false;\n",
2103 "\n",
2104 " this.ws.onopen = function () {\n",
2105 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
2106 " fig.send_message('send_image_mode', {});\n",
2107 " if (fig.ratio !== 1) {\n",
2108 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
2109 " }\n",
2110 " fig.send_message('refresh', {});\n",
2111 " };\n",
2112 "\n",
2113 " this.imageObj.onload = function () {\n",
2114 " if (fig.image_mode === 'full') {\n",
2115 " // Full images could contain transparency (where diff images\n",
2116 " // almost always do), so we need to clear the canvas so that\n",
2117 " // there is no ghosting.\n",
2118 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
2119 " }\n",
2120 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
2121 " };\n",
2122 "\n",
2123 " this.imageObj.onunload = function () {\n",
2124 " fig.ws.close();\n",
2125 " };\n",
2126 "\n",
2127 " this.ws.onmessage = this._make_on_message_function(this);\n",
2128 "\n",
2129 " this.ondownload = ondownload;\n",
2130 "};\n",
2131 "\n",
2132 "mpl.figure.prototype._init_header = function () {\n",
2133 " var titlebar = document.createElement('div');\n",
2134 " titlebar.classList =\n",
2135 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
2136 " var titletext = document.createElement('div');\n",
2137 " titletext.classList = 'ui-dialog-title';\n",
2138 " titletext.setAttribute(\n",
2139 " 'style',\n",
2140 " 'width: 100%; text-align: center; padding: 3px;'\n",
2141 " );\n",
2142 " titlebar.appendChild(titletext);\n",
2143 " this.root.appendChild(titlebar);\n",
2144 " this.header = titletext;\n",
2145 "};\n",
2146 "\n",
2147 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
2148 "\n",
2149 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
2150 "\n",
2151 "mpl.figure.prototype._init_canvas = function () {\n",
2152 " var fig = this;\n",
2153 "\n",
2154 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
2155 " canvas_div.setAttribute(\n",
2156 " 'style',\n",
2157 " 'border: 1px solid #ddd;' +\n",
2158 " 'box-sizing: content-box;' +\n",
2159 " 'clear: both;' +\n",
2160 " 'min-height: 1px;' +\n",
2161 " 'min-width: 1px;' +\n",
2162 " 'outline: 0;' +\n",
2163 " 'overflow: hidden;' +\n",
2164 " 'position: relative;' +\n",
2165 " 'resize: both;'\n",
2166 " );\n",
2167 "\n",
2168 " function on_keyboard_event_closure(name) {\n",
2169 " return function (event) {\n",
2170 " return fig.key_event(event, name);\n",
2171 " };\n",
2172 " }\n",
2173 "\n",
2174 " canvas_div.addEventListener(\n",
2175 " 'keydown',\n",
2176 " on_keyboard_event_closure('key_press')\n",
2177 " );\n",
2178 " canvas_div.addEventListener(\n",
2179 " 'keyup',\n",
2180 " on_keyboard_event_closure('key_release')\n",
2181 " );\n",
2182 "\n",
2183 " this._canvas_extra_style(canvas_div);\n",
2184 " this.root.appendChild(canvas_div);\n",
2185 "\n",
2186 " var canvas = (this.canvas = document.createElement('canvas'));\n",
2187 " canvas.classList.add('mpl-canvas');\n",
2188 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
2189 "\n",
2190 " this.context = canvas.getContext('2d');\n",
2191 "\n",
2192 " var backingStore =\n",
2193 " this.context.backingStorePixelRatio ||\n",
2194 " this.context.webkitBackingStorePixelRatio ||\n",
2195 " this.context.mozBackingStorePixelRatio ||\n",
2196 " this.context.msBackingStorePixelRatio ||\n",
2197 " this.context.oBackingStorePixelRatio ||\n",
2198 " this.context.backingStorePixelRatio ||\n",
2199 " 1;\n",
2200 "\n",
2201 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
2202 "\n",
2203 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
2204 " 'canvas'\n",
2205 " ));\n",
2206 " rubberband_canvas.setAttribute(\n",
2207 " 'style',\n",
2208 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
2209 " );\n",
2210 "\n",
2211 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
2212 " if (this.ResizeObserver === undefined) {\n",
2213 " if (window.ResizeObserver !== undefined) {\n",
2214 " this.ResizeObserver = window.ResizeObserver;\n",
2215 " } else {\n",
2216 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
2217 " this.ResizeObserver = obs.ResizeObserver;\n",
2218 " }\n",
2219 " }\n",
2220 "\n",
2221 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
2222 " var nentries = entries.length;\n",
2223 " for (var i = 0; i < nentries; i++) {\n",
2224 " var entry = entries[i];\n",
2225 " var width, height;\n",
2226 " if (entry.contentBoxSize) {\n",
2227 " if (entry.contentBoxSize instanceof Array) {\n",
2228 " // Chrome 84 implements new version of spec.\n",
2229 " width = entry.contentBoxSize[0].inlineSize;\n",
2230 " height = entry.contentBoxSize[0].blockSize;\n",
2231 " } else {\n",
2232 " // Firefox implements old version of spec.\n",
2233 " width = entry.contentBoxSize.inlineSize;\n",
2234 " height = entry.contentBoxSize.blockSize;\n",
2235 " }\n",
2236 " } else {\n",
2237 " // Chrome <84 implements even older version of spec.\n",
2238 " width = entry.contentRect.width;\n",
2239 " height = entry.contentRect.height;\n",
2240 " }\n",
2241 "\n",
2242 " // Keep the size of the canvas and rubber band canvas in sync with\n",
2243 " // the canvas container.\n",
2244 " if (entry.devicePixelContentBoxSize) {\n",
2245 " // Chrome 84 implements new version of spec.\n",
2246 " canvas.setAttribute(\n",
2247 " 'width',\n",
2248 " entry.devicePixelContentBoxSize[0].inlineSize\n",
2249 " );\n",
2250 " canvas.setAttribute(\n",
2251 " 'height',\n",
2252 " entry.devicePixelContentBoxSize[0].blockSize\n",
2253 " );\n",
2254 " } else {\n",
2255 " canvas.setAttribute('width', width * fig.ratio);\n",
2256 " canvas.setAttribute('height', height * fig.ratio);\n",
2257 " }\n",
2258 " canvas.setAttribute(\n",
2259 " 'style',\n",
2260 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
2261 " );\n",
2262 "\n",
2263 " rubberband_canvas.setAttribute('width', width);\n",
2264 " rubberband_canvas.setAttribute('height', height);\n",
2265 "\n",
2266 " // And update the size in Python. We ignore the initial 0/0 size\n",
2267 " // that occurs as the element is placed into the DOM, which should\n",
2268 " // otherwise not happen due to the minimum size styling.\n",
2269 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
2270 " fig.request_resize(width, height);\n",
2271 " }\n",
2272 " }\n",
2273 " });\n",
2274 " this.resizeObserverInstance.observe(canvas_div);\n",
2275 "\n",
2276 " function on_mouse_event_closure(name) {\n",
2277 " return function (event) {\n",
2278 " return fig.mouse_event(event, name);\n",
2279 " };\n",
2280 " }\n",
2281 "\n",
2282 " rubberband_canvas.addEventListener(\n",
2283 " 'mousedown',\n",
2284 " on_mouse_event_closure('button_press')\n",
2285 " );\n",
2286 " rubberband_canvas.addEventListener(\n",
2287 " 'mouseup',\n",
2288 " on_mouse_event_closure('button_release')\n",
2289 " );\n",
2290 " // Throttle sequential mouse events to 1 every 20ms.\n",
2291 " rubberband_canvas.addEventListener(\n",
2292 " 'mousemove',\n",
2293 " on_mouse_event_closure('motion_notify')\n",
2294 " );\n",
2295 "\n",
2296 " rubberband_canvas.addEventListener(\n",
2297 " 'mouseenter',\n",
2298 " on_mouse_event_closure('figure_enter')\n",
2299 " );\n",
2300 " rubberband_canvas.addEventListener(\n",
2301 " 'mouseleave',\n",
2302 " on_mouse_event_closure('figure_leave')\n",
2303 " );\n",
2304 "\n",
2305 " canvas_div.addEventListener('wheel', function (event) {\n",
2306 " if (event.deltaY < 0) {\n",
2307 " event.step = 1;\n",
2308 " } else {\n",
2309 " event.step = -1;\n",
2310 " }\n",
2311 " on_mouse_event_closure('scroll')(event);\n",
2312 " });\n",
2313 "\n",
2314 " canvas_div.appendChild(canvas);\n",
2315 " canvas_div.appendChild(rubberband_canvas);\n",
2316 "\n",
2317 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
2318 " this.rubberband_context.strokeStyle = '#000000';\n",
2319 "\n",
2320 " this._resize_canvas = function (width, height, forward) {\n",
2321 " if (forward) {\n",
2322 " canvas_div.style.width = width + 'px';\n",
2323 " canvas_div.style.height = height + 'px';\n",
2324 " }\n",
2325 " };\n",
2326 "\n",
2327 " // Disable right mouse context menu.\n",
2328 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
2329 " event.preventDefault();\n",
2330 " return false;\n",
2331 " });\n",
2332 "\n",
2333 " function set_focus() {\n",
2334 " canvas.focus();\n",
2335 " canvas_div.focus();\n",
2336 " }\n",
2337 "\n",
2338 " window.setTimeout(set_focus, 100);\n",
2339 "};\n",
2340 "\n",
2341 "mpl.figure.prototype._init_toolbar = function () {\n",
2342 " var fig = this;\n",
2343 "\n",
2344 " var toolbar = document.createElement('div');\n",
2345 " toolbar.classList = 'mpl-toolbar';\n",
2346 " this.root.appendChild(toolbar);\n",
2347 "\n",
2348 " function on_click_closure(name) {\n",
2349 " return function (_event) {\n",
2350 " return fig.toolbar_button_onclick(name);\n",
2351 " };\n",
2352 " }\n",
2353 "\n",
2354 " function on_mouseover_closure(tooltip) {\n",
2355 " return function (event) {\n",
2356 " if (!event.currentTarget.disabled) {\n",
2357 " return fig.toolbar_button_onmouseover(tooltip);\n",
2358 " }\n",
2359 " };\n",
2360 " }\n",
2361 "\n",
2362 " fig.buttons = {};\n",
2363 " var buttonGroup = document.createElement('div');\n",
2364 " buttonGroup.classList = 'mpl-button-group';\n",
2365 " for (var toolbar_ind in mpl.toolbar_items) {\n",
2366 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
2367 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
2368 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
2369 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
2370 "\n",
2371 " if (!name) {\n",
2372 " /* Instead of a spacer, we start a new button group. */\n",
2373 " if (buttonGroup.hasChildNodes()) {\n",
2374 " toolbar.appendChild(buttonGroup);\n",
2375 " }\n",
2376 " buttonGroup = document.createElement('div');\n",
2377 " buttonGroup.classList = 'mpl-button-group';\n",
2378 " continue;\n",
2379 " }\n",
2380 "\n",
2381 " var button = (fig.buttons[name] = document.createElement('button'));\n",
2382 " button.classList = 'mpl-widget';\n",
2383 " button.setAttribute('role', 'button');\n",
2384 " button.setAttribute('aria-disabled', 'false');\n",
2385 " button.addEventListener('click', on_click_closure(method_name));\n",
2386 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
2387 "\n",
2388 " var icon_img = document.createElement('img');\n",
2389 " icon_img.src = '_images/' + image + '.png';\n",
2390 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
2391 " icon_img.alt = tooltip;\n",
2392 " button.appendChild(icon_img);\n",
2393 "\n",
2394 " buttonGroup.appendChild(button);\n",
2395 " }\n",
2396 "\n",
2397 " if (buttonGroup.hasChildNodes()) {\n",
2398 " toolbar.appendChild(buttonGroup);\n",
2399 " }\n",
2400 "\n",
2401 " var fmt_picker = document.createElement('select');\n",
2402 " fmt_picker.classList = 'mpl-widget';\n",
2403 " toolbar.appendChild(fmt_picker);\n",
2404 " this.format_dropdown = fmt_picker;\n",
2405 "\n",
2406 " for (var ind in mpl.extensions) {\n",
2407 " var fmt = mpl.extensions[ind];\n",
2408 " var option = document.createElement('option');\n",
2409 " option.selected = fmt === mpl.default_extension;\n",
2410 " option.innerHTML = fmt;\n",
2411 " fmt_picker.appendChild(option);\n",
2412 " }\n",
2413 "\n",
2414 " var status_bar = document.createElement('span');\n",
2415 " status_bar.classList = 'mpl-message';\n",
2416 " toolbar.appendChild(status_bar);\n",
2417 " this.message = status_bar;\n",
2418 "};\n",
2419 "\n",
2420 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
2421 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
2422 " // which will in turn request a refresh of the image.\n",
2423 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
2424 "};\n",
2425 "\n",
2426 "mpl.figure.prototype.send_message = function (type, properties) {\n",
2427 " properties['type'] = type;\n",
2428 " properties['figure_id'] = this.id;\n",
2429 " this.ws.send(JSON.stringify(properties));\n",
2430 "};\n",
2431 "\n",
2432 "mpl.figure.prototype.send_draw_message = function () {\n",
2433 " if (!this.waiting) {\n",
2434 " this.waiting = true;\n",
2435 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
2436 " }\n",
2437 "};\n",
2438 "\n",
2439 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
2440 " var format_dropdown = fig.format_dropdown;\n",
2441 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
2442 " fig.ondownload(fig, format);\n",
2443 "};\n",
2444 "\n",
2445 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
2446 " var size = msg['size'];\n",
2447 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
2448 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
2449 " fig.send_message('refresh', {});\n",
2450 " }\n",
2451 "};\n",
2452 "\n",
2453 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
2454 " var x0 = msg['x0'] / fig.ratio;\n",
2455 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
2456 " var x1 = msg['x1'] / fig.ratio;\n",
2457 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
2458 " x0 = Math.floor(x0) + 0.5;\n",
2459 " y0 = Math.floor(y0) + 0.5;\n",
2460 " x1 = Math.floor(x1) + 0.5;\n",
2461 " y1 = Math.floor(y1) + 0.5;\n",
2462 " var min_x = Math.min(x0, x1);\n",
2463 " var min_y = Math.min(y0, y1);\n",
2464 " var width = Math.abs(x1 - x0);\n",
2465 " var height = Math.abs(y1 - y0);\n",
2466 "\n",
2467 " fig.rubberband_context.clearRect(\n",
2468 " 0,\n",
2469 " 0,\n",
2470 " fig.canvas.width / fig.ratio,\n",
2471 " fig.canvas.height / fig.ratio\n",
2472 " );\n",
2473 "\n",
2474 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
2475 "};\n",
2476 "\n",
2477 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
2478 " // Updates the figure title.\n",
2479 " fig.header.textContent = msg['label'];\n",
2480 "};\n",
2481 "\n",
2482 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
2483 " var cursor = msg['cursor'];\n",
2484 " switch (cursor) {\n",
2485 " case 0:\n",
2486 " cursor = 'pointer';\n",
2487 " break;\n",
2488 " case 1:\n",
2489 " cursor = 'default';\n",
2490 " break;\n",
2491 " case 2:\n",
2492 " cursor = 'crosshair';\n",
2493 " break;\n",
2494 " case 3:\n",
2495 " cursor = 'move';\n",
2496 " break;\n",
2497 " }\n",
2498 " fig.rubberband_canvas.style.cursor = cursor;\n",
2499 "};\n",
2500 "\n",
2501 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
2502 " fig.message.textContent = msg['message'];\n",
2503 "};\n",
2504 "\n",
2505 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
2506 " // Request the server to send over a new figure.\n",
2507 " fig.send_draw_message();\n",
2508 "};\n",
2509 "\n",
2510 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
2511 " fig.image_mode = msg['mode'];\n",
2512 "};\n",
2513 "\n",
2514 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
2515 " for (var key in msg) {\n",
2516 " if (!(key in fig.buttons)) {\n",
2517 " continue;\n",
2518 " }\n",
2519 " fig.buttons[key].disabled = !msg[key];\n",
2520 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
2521 " }\n",
2522 "};\n",
2523 "\n",
2524 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
2525 " if (msg['mode'] === 'PAN') {\n",
2526 " fig.buttons['Pan'].classList.add('active');\n",
2527 " fig.buttons['Zoom'].classList.remove('active');\n",
2528 " } else if (msg['mode'] === 'ZOOM') {\n",
2529 " fig.buttons['Pan'].classList.remove('active');\n",
2530 " fig.buttons['Zoom'].classList.add('active');\n",
2531 " } else {\n",
2532 " fig.buttons['Pan'].classList.remove('active');\n",
2533 " fig.buttons['Zoom'].classList.remove('active');\n",
2534 " }\n",
2535 "};\n",
2536 "\n",
2537 "mpl.figure.prototype.updated_canvas_event = function () {\n",
2538 " // Called whenever the canvas gets updated.\n",
2539 " this.send_message('ack', {});\n",
2540 "};\n",
2541 "\n",
2542 "// A function to construct a web socket function for onmessage handling.\n",
2543 "// Called in the figure constructor.\n",
2544 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
2545 " return function socket_on_message(evt) {\n",
2546 " if (evt.data instanceof Blob) {\n",
2547 " /* FIXME: We get \"Resource interpreted as Image but\n",
2548 " * transferred with MIME type text/plain:\" errors on\n",
2549 " * Chrome. But how to set the MIME type? It doesn't seem\n",
2550 " * to be part of the websocket stream */\n",
2551 " evt.data.type = 'image/png';\n",
2552 "\n",
2553 " /* Free the memory for the previous frames */\n",
2554 " if (fig.imageObj.src) {\n",
2555 " (window.URL || window.webkitURL).revokeObjectURL(\n",
2556 " fig.imageObj.src\n",
2557 " );\n",
2558 " }\n",
2559 "\n",
2560 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
2561 " evt.data\n",
2562 " );\n",
2563 " fig.updated_canvas_event();\n",
2564 " fig.waiting = false;\n",
2565 " return;\n",
2566 " } else if (\n",
2567 " typeof evt.data === 'string' &&\n",
2568 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
2569 " ) {\n",
2570 " fig.imageObj.src = evt.data;\n",
2571 " fig.updated_canvas_event();\n",
2572 " fig.waiting = false;\n",
2573 " return;\n",
2574 " }\n",
2575 "\n",
2576 " var msg = JSON.parse(evt.data);\n",
2577 " var msg_type = msg['type'];\n",
2578 "\n",
2579 " // Call the \"handle_{type}\" callback, which takes\n",
2580 " // the figure and JSON message as its only arguments.\n",
2581 " try {\n",
2582 " var callback = fig['handle_' + msg_type];\n",
2583 " } catch (e) {\n",
2584 " console.log(\n",
2585 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
2586 " msg\n",
2587 " );\n",
2588 " return;\n",
2589 " }\n",
2590 "\n",
2591 " if (callback) {\n",
2592 " try {\n",
2593 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
2594 " callback(fig, msg);\n",
2595 " } catch (e) {\n",
2596 " console.log(\n",
2597 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
2598 " e,\n",
2599 " e.stack,\n",
2600 " msg\n",
2601 " );\n",
2602 " }\n",
2603 " }\n",
2604 " };\n",
2605 "};\n",
2606 "\n",
2607 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
2608 "mpl.findpos = function (e) {\n",
2609 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
2610 " var targ;\n",
2611 " if (!e) {\n",
2612 " e = window.event;\n",
2613 " }\n",
2614 " if (e.target) {\n",
2615 " targ = e.target;\n",
2616 " } else if (e.srcElement) {\n",
2617 " targ = e.srcElement;\n",
2618 " }\n",
2619 " if (targ.nodeType === 3) {\n",
2620 " // defeat Safari bug\n",
2621 " targ = targ.parentNode;\n",
2622 " }\n",
2623 "\n",
2624 " // pageX,Y are the mouse positions relative to the document\n",
2625 " var boundingRect = targ.getBoundingClientRect();\n",
2626 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
2627 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
2628 "\n",
2629 " return { x: x, y: y };\n",
2630 "};\n",
2631 "\n",
2632 "/*\n",
2633 " * return a copy of an object with only non-object keys\n",
2634 " * we need this to avoid circular references\n",
2635 " * http://stackoverflow.com/a/24161582/3208463\n",
2636 " */\n",
2637 "function simpleKeys(original) {\n",
2638 " return Object.keys(original).reduce(function (obj, key) {\n",
2639 " if (typeof original[key] !== 'object') {\n",
2640 " obj[key] = original[key];\n",
2641 " }\n",
2642 " return obj;\n",
2643 " }, {});\n",
2644 "}\n",
2645 "\n",
2646 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
2647 " var canvas_pos = mpl.findpos(event);\n",
2648 "\n",
2649 " if (name === 'button_press') {\n",
2650 " this.canvas.focus();\n",
2651 " this.canvas_div.focus();\n",
2652 " }\n",
2653 "\n",
2654 " var x = canvas_pos.x * this.ratio;\n",
2655 " var y = canvas_pos.y * this.ratio;\n",
2656 "\n",
2657 " this.send_message(name, {\n",
2658 " x: x,\n",
2659 " y: y,\n",
2660 " button: event.button,\n",
2661 " step: event.step,\n",
2662 " guiEvent: simpleKeys(event),\n",
2663 " });\n",
2664 "\n",
2665 " /* This prevents the web browser from automatically changing to\n",
2666 " * the text insertion cursor when the button is pressed. We want\n",
2667 " * to control all of the cursor setting manually through the\n",
2668 " * 'cursor' event from matplotlib */\n",
2669 " event.preventDefault();\n",
2670 " return false;\n",
2671 "};\n",
2672 "\n",
2673 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
2674 " // Handle any extra behaviour associated with a key event\n",
2675 "};\n",
2676 "\n",
2677 "mpl.figure.prototype.key_event = function (event, name) {\n",
2678 " // Prevent repeat events\n",
2679 " if (name === 'key_press') {\n",
2680 " if (event.which === this._key) {\n",
2681 " return;\n",
2682 " } else {\n",
2683 " this._key = event.which;\n",
2684 " }\n",
2685 " }\n",
2686 " if (name === 'key_release') {\n",
2687 " this._key = null;\n",
2688 " }\n",
2689 "\n",
2690 " var value = '';\n",
2691 " if (event.ctrlKey && event.which !== 17) {\n",
2692 " value += 'ctrl+';\n",
2693 " }\n",
2694 " if (event.altKey && event.which !== 18) {\n",
2695 " value += 'alt+';\n",
2696 " }\n",
2697 " if (event.shiftKey && event.which !== 16) {\n",
2698 " value += 'shift+';\n",
2699 " }\n",
2700 "\n",
2701 " value += 'k';\n",
2702 " value += event.which.toString();\n",
2703 "\n",
2704 " this._key_event_extra(event, name);\n",
2705 "\n",
2706 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
2707 " return false;\n",
2708 "};\n",
2709 "\n",
2710 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
2711 " if (name === 'download') {\n",
2712 " this.handle_save(this, null);\n",
2713 " } else {\n",
2714 " this.send_message('toolbar_button', { name: name });\n",
2715 " }\n",
2716 "};\n",
2717 "\n",
2718 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
2719 " this.message.textContent = tooltip;\n",
2720 "};\n",
2721 "\n",
2722 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
2723 "// prettier-ignore\n",
2724 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
2725 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
2726 "\n",
2727 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
2728 "\n",
2729 "mpl.default_extension = \"png\";/* global mpl */\n",
2730 "\n",
2731 "var comm_websocket_adapter = function (comm) {\n",
2732 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
2733 " // object with the appropriate methods. Currently this is a non binary\n",
2734 " // socket, so there is still some room for performance tuning.\n",
2735 " var ws = {};\n",
2736 "\n",
2737 " ws.close = function () {\n",
2738 " comm.close();\n",
2739 " };\n",
2740 " ws.send = function (m) {\n",
2741 " //console.log('sending', m);\n",
2742 " comm.send(m);\n",
2743 " };\n",
2744 " // Register the callback with on_msg.\n",
2745 " comm.on_msg(function (msg) {\n",
2746 " //console.log('receiving', msg['content']['data'], msg);\n",
2747 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
2748 " ws.onmessage(msg['content']['data']);\n",
2749 " });\n",
2750 " return ws;\n",
2751 "};\n",
2752 "\n",
2753 "mpl.mpl_figure_comm = function (comm, msg) {\n",
2754 " // This is the function which gets called when the mpl process\n",
2755 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
2756 "\n",
2757 " var id = msg.content.data.id;\n",
2758 " // Get hold of the div created by the display call when the Comm\n",
2759 " // socket was opened in Python.\n",
2760 " var element = document.getElementById(id);\n",
2761 " var ws_proxy = comm_websocket_adapter(comm);\n",
2762 "\n",
2763 " function ondownload(figure, _format) {\n",
2764 " window.open(figure.canvas.toDataURL());\n",
2765 " }\n",
2766 "\n",
2767 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
2768 "\n",
2769 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
2770 " // web socket which is closed, not our websocket->open comm proxy.\n",
2771 " ws_proxy.onopen();\n",
2772 "\n",
2773 " fig.parent_element = element;\n",
2774 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
2775 " if (!fig.cell_info) {\n",
2776 " console.error('Failed to find cell for figure', id, fig);\n",
2777 " return;\n",
2778 " }\n",
2779 " fig.cell_info[0].output_area.element.on(\n",
2780 " 'cleared',\n",
2781 " { fig: fig },\n",
2782 " fig._remove_fig_handler\n",
2783 " );\n",
2784 "};\n",
2785 "\n",
2786 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
2787 " var width = fig.canvas.width / fig.ratio;\n",
2788 " fig.cell_info[0].output_area.element.off(\n",
2789 " 'cleared',\n",
2790 " fig._remove_fig_handler\n",
2791 " );\n",
2792 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
2793 "\n",
2794 " // Update the output cell to use the data from the current canvas.\n",
2795 " fig.push_to_output();\n",
2796 " var dataURL = fig.canvas.toDataURL();\n",
2797 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
2798 " // the notebook keyboard shortcuts fail.\n",
2799 " IPython.keyboard_manager.enable();\n",
2800 " fig.parent_element.innerHTML =\n",
2801 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
2802 " fig.close_ws(fig, msg);\n",
2803 "};\n",
2804 "\n",
2805 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
2806 " fig.send_message('closing', msg);\n",
2807 " // fig.ws.close()\n",
2808 "};\n",
2809 "\n",
2810 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
2811 " // Turn the data on the canvas into data in the output cell.\n",
2812 " var width = this.canvas.width / this.ratio;\n",
2813 " var dataURL = this.canvas.toDataURL();\n",
2814 " this.cell_info[1]['text/html'] =\n",
2815 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
2816 "};\n",
2817 "\n",
2818 "mpl.figure.prototype.updated_canvas_event = function () {\n",
2819 " // Tell IPython that the notebook contents must change.\n",
2820 " IPython.notebook.set_dirty(true);\n",
2821 " this.send_message('ack', {});\n",
2822 " var fig = this;\n",
2823 " // Wait a second, then push the new image to the DOM so\n",
2824 " // that it is saved nicely (might be nice to debounce this).\n",
2825 " setTimeout(function () {\n",
2826 " fig.push_to_output();\n",
2827 " }, 1000);\n",
2828 "};\n",
2829 "\n",
2830 "mpl.figure.prototype._init_toolbar = function () {\n",
2831 " var fig = this;\n",
2832 "\n",
2833 " var toolbar = document.createElement('div');\n",
2834 " toolbar.classList = 'btn-toolbar';\n",
2835 " this.root.appendChild(toolbar);\n",
2836 "\n",
2837 " function on_click_closure(name) {\n",
2838 " return function (_event) {\n",
2839 " return fig.toolbar_button_onclick(name);\n",
2840 " };\n",
2841 " }\n",
2842 "\n",
2843 " function on_mouseover_closure(tooltip) {\n",
2844 " return function (event) {\n",
2845 " if (!event.currentTarget.disabled) {\n",
2846 " return fig.toolbar_button_onmouseover(tooltip);\n",
2847 " }\n",
2848 " };\n",
2849 " }\n",
2850 "\n",
2851 " fig.buttons = {};\n",
2852 " var buttonGroup = document.createElement('div');\n",
2853 " buttonGroup.classList = 'btn-group';\n",
2854 " var button;\n",
2855 " for (var toolbar_ind in mpl.toolbar_items) {\n",
2856 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
2857 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
2858 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
2859 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
2860 "\n",
2861 " if (!name) {\n",
2862 " /* Instead of a spacer, we start a new button group. */\n",
2863 " if (buttonGroup.hasChildNodes()) {\n",
2864 " toolbar.appendChild(buttonGroup);\n",
2865 " }\n",
2866 " buttonGroup = document.createElement('div');\n",
2867 " buttonGroup.classList = 'btn-group';\n",
2868 " continue;\n",
2869 " }\n",
2870 "\n",
2871 " button = fig.buttons[name] = document.createElement('button');\n",
2872 " button.classList = 'btn btn-default';\n",
2873 " button.href = '#';\n",
2874 " button.title = name;\n",
2875 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
2876 " button.addEventListener('click', on_click_closure(method_name));\n",
2877 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
2878 " buttonGroup.appendChild(button);\n",
2879 " }\n",
2880 "\n",
2881 " if (buttonGroup.hasChildNodes()) {\n",
2882 " toolbar.appendChild(buttonGroup);\n",
2883 " }\n",
2884 "\n",
2885 " // Add the status bar.\n",
2886 " var status_bar = document.createElement('span');\n",
2887 " status_bar.classList = 'mpl-message pull-right';\n",
2888 " toolbar.appendChild(status_bar);\n",
2889 " this.message = status_bar;\n",
2890 "\n",
2891 " // Add the close button to the window.\n",
2892 " var buttongrp = document.createElement('div');\n",
2893 " buttongrp.classList = 'btn-group inline pull-right';\n",
2894 " button = document.createElement('button');\n",
2895 " button.classList = 'btn btn-mini btn-primary';\n",
2896 " button.href = '#';\n",
2897 " button.title = 'Stop Interaction';\n",
2898 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
2899 " button.addEventListener('click', function (_evt) {\n",
2900 " fig.handle_close(fig, {});\n",
2901 " });\n",
2902 " button.addEventListener(\n",
2903 " 'mouseover',\n",
2904 " on_mouseover_closure('Stop Interaction')\n",
2905 " );\n",
2906 " buttongrp.appendChild(button);\n",
2907 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
2908 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
2909 "};\n",
2910 "\n",
2911 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
2912 " var fig = event.data.fig;\n",
2913 " if (event.target !== this) {\n",
2914 " // Ignore bubbled events from children.\n",
2915 " return;\n",
2916 " }\n",
2917 " fig.close_ws(fig, {});\n",
2918 "};\n",
2919 "\n",
2920 "mpl.figure.prototype._root_extra_style = function (el) {\n",
2921 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
2922 "};\n",
2923 "\n",
2924 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
2925 " // this is important to make the div 'focusable\n",
2926 " el.setAttribute('tabindex', 0);\n",
2927 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
2928 " // off when our div gets focus\n",
2929 "\n",
2930 " // location in version 3\n",
2931 " if (IPython.notebook.keyboard_manager) {\n",
2932 " IPython.notebook.keyboard_manager.register_events(el);\n",
2933 " } else {\n",
2934 " // location in version 2\n",
2935 " IPython.keyboard_manager.register_events(el);\n",
2936 " }\n",
2937 "};\n",
2938 "\n",
2939 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
2940 " var manager = IPython.notebook.keyboard_manager;\n",
2941 " if (!manager) {\n",
2942 " manager = IPython.keyboard_manager;\n",
2943 " }\n",
2944 "\n",
2945 " // Check for shift+enter\n",
2946 " if (event.shiftKey && event.which === 13) {\n",
2947 " this.canvas_div.blur();\n",
2948 " // select the cell after this one\n",
2949 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
2950 " IPython.notebook.select(index + 1);\n",
2951 " }\n",
2952 "};\n",
2953 "\n",
2954 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
2955 " fig.ondownload(fig, null);\n",
2956 "};\n",
2957 "\n",
2958 "mpl.find_output_cell = function (html_output) {\n",
2959 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
2960 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
2961 " // IPython event is triggered only after the cells have been serialised, which for\n",
2962 " // our purposes (turning an active figure into a static one), is too late.\n",
2963 " var cells = IPython.notebook.get_cells();\n",
2964 " var ncells = cells.length;\n",
2965 " for (var i = 0; i < ncells; i++) {\n",
2966 " var cell = cells[i];\n",
2967 " if (cell.cell_type === 'code') {\n",
2968 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
2969 " var data = cell.output_area.outputs[j];\n",
2970 " if (data.data) {\n",
2971 " // IPython >= 3 moved mimebundle to data attribute of output\n",
2972 " data = data.data;\n",
2973 " }\n",
2974 " if (data['text/html'] === html_output) {\n",
2975 " return [cell, data, j];\n",
2976 " }\n",
2977 " }\n",
2978 " }\n",
2979 " }\n",
2980 "};\n",
2981 "\n",
2982 "// Register the function which deals with the matplotlib target/channel.\n",
2983 "// The kernel may be null if the page has been refreshed.\n",
2984 "if (IPython.notebook.kernel !== null) {\n",
2985 " IPython.notebook.kernel.comm_manager.register_target(\n",
2986 " 'matplotlib',\n",
2987 " mpl.mpl_figure_comm\n",
2988 " );\n",
2989 "}\n"
2990 ],
2991 "text/plain": [
2992 "<IPython.core.display.Javascript object>"
2993 ]
2994 },
2995 "metadata": {},
2996 "output_type": "display_data"
2997 },
2998 {
2999 "data": {
3000 "text/html": [
3001 "<div id='95d27d01-6329-4454-a292-133d62c8976b'></div>"
3002 ],
3003 "text/plain": [
3004 "<IPython.core.display.HTML object>"
3005 ]
3006 },
3007 "metadata": {},
3008 "output_type": "display_data"
3009 },
3010 {
3011 "data": {
3012 "application/javascript": [
3013 "/* Put everything inside the global mpl namespace */\n",
3014 "/* global mpl */\n",
3015 "window.mpl = {};\n",
3016 "\n",
3017 "mpl.get_websocket_type = function () {\n",
3018 " if (typeof WebSocket !== 'undefined') {\n",
3019 " return WebSocket;\n",
3020 " } else if (typeof MozWebSocket !== 'undefined') {\n",
3021 " return MozWebSocket;\n",
3022 " } else {\n",
3023 " alert(\n",
3024 " 'Your browser does not have WebSocket support. ' +\n",
3025 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
3026 " 'Firefox 4 and 5 are also supported but you ' +\n",
3027 " 'have to enable WebSockets in about:config.'\n",
3028 " );\n",
3029 " }\n",
3030 "};\n",
3031 "\n",
3032 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
3033 " this.id = figure_id;\n",
3034 "\n",
3035 " this.ws = websocket;\n",
3036 "\n",
3037 " this.supports_binary = this.ws.binaryType !== undefined;\n",
3038 "\n",
3039 " if (!this.supports_binary) {\n",
3040 " var warnings = document.getElementById('mpl-warnings');\n",
3041 " if (warnings) {\n",
3042 " warnings.style.display = 'block';\n",
3043 " warnings.textContent =\n",
3044 " 'This browser does not support binary websocket messages. ' +\n",
3045 " 'Performance may be slow.';\n",
3046 " }\n",
3047 " }\n",
3048 "\n",
3049 " this.imageObj = new Image();\n",
3050 "\n",
3051 " this.context = undefined;\n",
3052 " this.message = undefined;\n",
3053 " this.canvas = undefined;\n",
3054 " this.rubberband_canvas = undefined;\n",
3055 " this.rubberband_context = undefined;\n",
3056 " this.format_dropdown = undefined;\n",
3057 "\n",
3058 " this.image_mode = 'full';\n",
3059 "\n",
3060 " this.root = document.createElement('div');\n",
3061 " this.root.setAttribute('style', 'display: inline-block');\n",
3062 " this._root_extra_style(this.root);\n",
3063 "\n",
3064 " parent_element.appendChild(this.root);\n",
3065 "\n",
3066 " this._init_header(this);\n",
3067 " this._init_canvas(this);\n",
3068 " this._init_toolbar(this);\n",
3069 "\n",
3070 " var fig = this;\n",
3071 "\n",
3072 " this.waiting = false;\n",
3073 "\n",
3074 " this.ws.onopen = function () {\n",
3075 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
3076 " fig.send_message('send_image_mode', {});\n",
3077 " if (fig.ratio !== 1) {\n",
3078 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
3079 " }\n",
3080 " fig.send_message('refresh', {});\n",
3081 " };\n",
3082 "\n",
3083 " this.imageObj.onload = function () {\n",
3084 " if (fig.image_mode === 'full') {\n",
3085 " // Full images could contain transparency (where diff images\n",
3086 " // almost always do), so we need to clear the canvas so that\n",
3087 " // there is no ghosting.\n",
3088 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
3089 " }\n",
3090 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
3091 " };\n",
3092 "\n",
3093 " this.imageObj.onunload = function () {\n",
3094 " fig.ws.close();\n",
3095 " };\n",
3096 "\n",
3097 " this.ws.onmessage = this._make_on_message_function(this);\n",
3098 "\n",
3099 " this.ondownload = ondownload;\n",
3100 "};\n",
3101 "\n",
3102 "mpl.figure.prototype._init_header = function () {\n",
3103 " var titlebar = document.createElement('div');\n",
3104 " titlebar.classList =\n",
3105 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
3106 " var titletext = document.createElement('div');\n",
3107 " titletext.classList = 'ui-dialog-title';\n",
3108 " titletext.setAttribute(\n",
3109 " 'style',\n",
3110 " 'width: 100%; text-align: center; padding: 3px;'\n",
3111 " );\n",
3112 " titlebar.appendChild(titletext);\n",
3113 " this.root.appendChild(titlebar);\n",
3114 " this.header = titletext;\n",
3115 "};\n",
3116 "\n",
3117 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
3118 "\n",
3119 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
3120 "\n",
3121 "mpl.figure.prototype._init_canvas = function () {\n",
3122 " var fig = this;\n",
3123 "\n",
3124 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
3125 " canvas_div.setAttribute(\n",
3126 " 'style',\n",
3127 " 'border: 1px solid #ddd;' +\n",
3128 " 'box-sizing: content-box;' +\n",
3129 " 'clear: both;' +\n",
3130 " 'min-height: 1px;' +\n",
3131 " 'min-width: 1px;' +\n",
3132 " 'outline: 0;' +\n",
3133 " 'overflow: hidden;' +\n",
3134 " 'position: relative;' +\n",
3135 " 'resize: both;'\n",
3136 " );\n",
3137 "\n",
3138 " function on_keyboard_event_closure(name) {\n",
3139 " return function (event) {\n",
3140 " return fig.key_event(event, name);\n",
3141 " };\n",
3142 " }\n",
3143 "\n",
3144 " canvas_div.addEventListener(\n",
3145 " 'keydown',\n",
3146 " on_keyboard_event_closure('key_press')\n",
3147 " );\n",
3148 " canvas_div.addEventListener(\n",
3149 " 'keyup',\n",
3150 " on_keyboard_event_closure('key_release')\n",
3151 " );\n",
3152 "\n",
3153 " this._canvas_extra_style(canvas_div);\n",
3154 " this.root.appendChild(canvas_div);\n",
3155 "\n",
3156 " var canvas = (this.canvas = document.createElement('canvas'));\n",
3157 " canvas.classList.add('mpl-canvas');\n",
3158 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
3159 "\n",
3160 " this.context = canvas.getContext('2d');\n",
3161 "\n",
3162 " var backingStore =\n",
3163 " this.context.backingStorePixelRatio ||\n",
3164 " this.context.webkitBackingStorePixelRatio ||\n",
3165 " this.context.mozBackingStorePixelRatio ||\n",
3166 " this.context.msBackingStorePixelRatio ||\n",
3167 " this.context.oBackingStorePixelRatio ||\n",
3168 " this.context.backingStorePixelRatio ||\n",
3169 " 1;\n",
3170 "\n",
3171 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
3172 "\n",
3173 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
3174 " 'canvas'\n",
3175 " ));\n",
3176 " rubberband_canvas.setAttribute(\n",
3177 " 'style',\n",
3178 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
3179 " );\n",
3180 "\n",
3181 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
3182 " if (this.ResizeObserver === undefined) {\n",
3183 " if (window.ResizeObserver !== undefined) {\n",
3184 " this.ResizeObserver = window.ResizeObserver;\n",
3185 " } else {\n",
3186 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
3187 " this.ResizeObserver = obs.ResizeObserver;\n",
3188 " }\n",
3189 " }\n",
3190 "\n",
3191 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
3192 " var nentries = entries.length;\n",
3193 " for (var i = 0; i < nentries; i++) {\n",
3194 " var entry = entries[i];\n",
3195 " var width, height;\n",
3196 " if (entry.contentBoxSize) {\n",
3197 " if (entry.contentBoxSize instanceof Array) {\n",
3198 " // Chrome 84 implements new version of spec.\n",
3199 " width = entry.contentBoxSize[0].inlineSize;\n",
3200 " height = entry.contentBoxSize[0].blockSize;\n",
3201 " } else {\n",
3202 " // Firefox implements old version of spec.\n",
3203 " width = entry.contentBoxSize.inlineSize;\n",
3204 " height = entry.contentBoxSize.blockSize;\n",
3205 " }\n",
3206 " } else {\n",
3207 " // Chrome <84 implements even older version of spec.\n",
3208 " width = entry.contentRect.width;\n",
3209 " height = entry.contentRect.height;\n",
3210 " }\n",
3211 "\n",
3212 " // Keep the size of the canvas and rubber band canvas in sync with\n",
3213 " // the canvas container.\n",
3214 " if (entry.devicePixelContentBoxSize) {\n",
3215 " // Chrome 84 implements new version of spec.\n",
3216 " canvas.setAttribute(\n",
3217 " 'width',\n",
3218 " entry.devicePixelContentBoxSize[0].inlineSize\n",
3219 " );\n",
3220 " canvas.setAttribute(\n",
3221 " 'height',\n",
3222 " entry.devicePixelContentBoxSize[0].blockSize\n",
3223 " );\n",
3224 " } else {\n",
3225 " canvas.setAttribute('width', width * fig.ratio);\n",
3226 " canvas.setAttribute('height', height * fig.ratio);\n",
3227 " }\n",
3228 " canvas.setAttribute(\n",
3229 " 'style',\n",
3230 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
3231 " );\n",
3232 "\n",
3233 " rubberband_canvas.setAttribute('width', width);\n",
3234 " rubberband_canvas.setAttribute('height', height);\n",
3235 "\n",
3236 " // And update the size in Python. We ignore the initial 0/0 size\n",
3237 " // that occurs as the element is placed into the DOM, which should\n",
3238 " // otherwise not happen due to the minimum size styling.\n",
3239 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
3240 " fig.request_resize(width, height);\n",
3241 " }\n",
3242 " }\n",
3243 " });\n",
3244 " this.resizeObserverInstance.observe(canvas_div);\n",
3245 "\n",
3246 " function on_mouse_event_closure(name) {\n",
3247 " return function (event) {\n",
3248 " return fig.mouse_event(event, name);\n",
3249 " };\n",
3250 " }\n",
3251 "\n",
3252 " rubberband_canvas.addEventListener(\n",
3253 " 'mousedown',\n",
3254 " on_mouse_event_closure('button_press')\n",
3255 " );\n",
3256 " rubberband_canvas.addEventListener(\n",
3257 " 'mouseup',\n",
3258 " on_mouse_event_closure('button_release')\n",
3259 " );\n",
3260 " // Throttle sequential mouse events to 1 every 20ms.\n",
3261 " rubberband_canvas.addEventListener(\n",
3262 " 'mousemove',\n",
3263 " on_mouse_event_closure('motion_notify')\n",
3264 " );\n",
3265 "\n",
3266 " rubberband_canvas.addEventListener(\n",
3267 " 'mouseenter',\n",
3268 " on_mouse_event_closure('figure_enter')\n",
3269 " );\n",
3270 " rubberband_canvas.addEventListener(\n",
3271 " 'mouseleave',\n",
3272 " on_mouse_event_closure('figure_leave')\n",
3273 " );\n",
3274 "\n",
3275 " canvas_div.addEventListener('wheel', function (event) {\n",
3276 " if (event.deltaY < 0) {\n",
3277 " event.step = 1;\n",
3278 " } else {\n",
3279 " event.step = -1;\n",
3280 " }\n",
3281 " on_mouse_event_closure('scroll')(event);\n",
3282 " });\n",
3283 "\n",
3284 " canvas_div.appendChild(canvas);\n",
3285 " canvas_div.appendChild(rubberband_canvas);\n",
3286 "\n",
3287 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
3288 " this.rubberband_context.strokeStyle = '#000000';\n",
3289 "\n",
3290 " this._resize_canvas = function (width, height, forward) {\n",
3291 " if (forward) {\n",
3292 " canvas_div.style.width = width + 'px';\n",
3293 " canvas_div.style.height = height + 'px';\n",
3294 " }\n",
3295 " };\n",
3296 "\n",
3297 " // Disable right mouse context menu.\n",
3298 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
3299 " event.preventDefault();\n",
3300 " return false;\n",
3301 " });\n",
3302 "\n",
3303 " function set_focus() {\n",
3304 " canvas.focus();\n",
3305 " canvas_div.focus();\n",
3306 " }\n",
3307 "\n",
3308 " window.setTimeout(set_focus, 100);\n",
3309 "};\n",
3310 "\n",
3311 "mpl.figure.prototype._init_toolbar = function () {\n",
3312 " var fig = this;\n",
3313 "\n",
3314 " var toolbar = document.createElement('div');\n",
3315 " toolbar.classList = 'mpl-toolbar';\n",
3316 " this.root.appendChild(toolbar);\n",
3317 "\n",
3318 " function on_click_closure(name) {\n",
3319 " return function (_event) {\n",
3320 " return fig.toolbar_button_onclick(name);\n",
3321 " };\n",
3322 " }\n",
3323 "\n",
3324 " function on_mouseover_closure(tooltip) {\n",
3325 " return function (event) {\n",
3326 " if (!event.currentTarget.disabled) {\n",
3327 " return fig.toolbar_button_onmouseover(tooltip);\n",
3328 " }\n",
3329 " };\n",
3330 " }\n",
3331 "\n",
3332 " fig.buttons = {};\n",
3333 " var buttonGroup = document.createElement('div');\n",
3334 " buttonGroup.classList = 'mpl-button-group';\n",
3335 " for (var toolbar_ind in mpl.toolbar_items) {\n",
3336 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
3337 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
3338 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
3339 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
3340 "\n",
3341 " if (!name) {\n",
3342 " /* Instead of a spacer, we start a new button group. */\n",
3343 " if (buttonGroup.hasChildNodes()) {\n",
3344 " toolbar.appendChild(buttonGroup);\n",
3345 " }\n",
3346 " buttonGroup = document.createElement('div');\n",
3347 " buttonGroup.classList = 'mpl-button-group';\n",
3348 " continue;\n",
3349 " }\n",
3350 "\n",
3351 " var button = (fig.buttons[name] = document.createElement('button'));\n",
3352 " button.classList = 'mpl-widget';\n",
3353 " button.setAttribute('role', 'button');\n",
3354 " button.setAttribute('aria-disabled', 'false');\n",
3355 " button.addEventListener('click', on_click_closure(method_name));\n",
3356 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
3357 "\n",
3358 " var icon_img = document.createElement('img');\n",
3359 " icon_img.src = '_images/' + image + '.png';\n",
3360 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
3361 " icon_img.alt = tooltip;\n",
3362 " button.appendChild(icon_img);\n",
3363 "\n",
3364 " buttonGroup.appendChild(button);\n",
3365 " }\n",
3366 "\n",
3367 " if (buttonGroup.hasChildNodes()) {\n",
3368 " toolbar.appendChild(buttonGroup);\n",
3369 " }\n",
3370 "\n",
3371 " var fmt_picker = document.createElement('select');\n",
3372 " fmt_picker.classList = 'mpl-widget';\n",
3373 " toolbar.appendChild(fmt_picker);\n",
3374 " this.format_dropdown = fmt_picker;\n",
3375 "\n",
3376 " for (var ind in mpl.extensions) {\n",
3377 " var fmt = mpl.extensions[ind];\n",
3378 " var option = document.createElement('option');\n",
3379 " option.selected = fmt === mpl.default_extension;\n",
3380 " option.innerHTML = fmt;\n",
3381 " fmt_picker.appendChild(option);\n",
3382 " }\n",
3383 "\n",
3384 " var status_bar = document.createElement('span');\n",
3385 " status_bar.classList = 'mpl-message';\n",
3386 " toolbar.appendChild(status_bar);\n",
3387 " this.message = status_bar;\n",
3388 "};\n",
3389 "\n",
3390 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
3391 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
3392 " // which will in turn request a refresh of the image.\n",
3393 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
3394 "};\n",
3395 "\n",
3396 "mpl.figure.prototype.send_message = function (type, properties) {\n",
3397 " properties['type'] = type;\n",
3398 " properties['figure_id'] = this.id;\n",
3399 " this.ws.send(JSON.stringify(properties));\n",
3400 "};\n",
3401 "\n",
3402 "mpl.figure.prototype.send_draw_message = function () {\n",
3403 " if (!this.waiting) {\n",
3404 " this.waiting = true;\n",
3405 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
3406 " }\n",
3407 "};\n",
3408 "\n",
3409 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
3410 " var format_dropdown = fig.format_dropdown;\n",
3411 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
3412 " fig.ondownload(fig, format);\n",
3413 "};\n",
3414 "\n",
3415 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
3416 " var size = msg['size'];\n",
3417 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
3418 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
3419 " fig.send_message('refresh', {});\n",
3420 " }\n",
3421 "};\n",
3422 "\n",
3423 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
3424 " var x0 = msg['x0'] / fig.ratio;\n",
3425 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
3426 " var x1 = msg['x1'] / fig.ratio;\n",
3427 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
3428 " x0 = Math.floor(x0) + 0.5;\n",
3429 " y0 = Math.floor(y0) + 0.5;\n",
3430 " x1 = Math.floor(x1) + 0.5;\n",
3431 " y1 = Math.floor(y1) + 0.5;\n",
3432 " var min_x = Math.min(x0, x1);\n",
3433 " var min_y = Math.min(y0, y1);\n",
3434 " var width = Math.abs(x1 - x0);\n",
3435 " var height = Math.abs(y1 - y0);\n",
3436 "\n",
3437 " fig.rubberband_context.clearRect(\n",
3438 " 0,\n",
3439 " 0,\n",
3440 " fig.canvas.width / fig.ratio,\n",
3441 " fig.canvas.height / fig.ratio\n",
3442 " );\n",
3443 "\n",
3444 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
3445 "};\n",
3446 "\n",
3447 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
3448 " // Updates the figure title.\n",
3449 " fig.header.textContent = msg['label'];\n",
3450 "};\n",
3451 "\n",
3452 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
3453 " var cursor = msg['cursor'];\n",
3454 " switch (cursor) {\n",
3455 " case 0:\n",
3456 " cursor = 'pointer';\n",
3457 " break;\n",
3458 " case 1:\n",
3459 " cursor = 'default';\n",
3460 " break;\n",
3461 " case 2:\n",
3462 " cursor = 'crosshair';\n",
3463 " break;\n",
3464 " case 3:\n",
3465 " cursor = 'move';\n",
3466 " break;\n",
3467 " }\n",
3468 " fig.rubberband_canvas.style.cursor = cursor;\n",
3469 "};\n",
3470 "\n",
3471 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
3472 " fig.message.textContent = msg['message'];\n",
3473 "};\n",
3474 "\n",
3475 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
3476 " // Request the server to send over a new figure.\n",
3477 " fig.send_draw_message();\n",
3478 "};\n",
3479 "\n",
3480 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
3481 " fig.image_mode = msg['mode'];\n",
3482 "};\n",
3483 "\n",
3484 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
3485 " for (var key in msg) {\n",
3486 " if (!(key in fig.buttons)) {\n",
3487 " continue;\n",
3488 " }\n",
3489 " fig.buttons[key].disabled = !msg[key];\n",
3490 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
3491 " }\n",
3492 "};\n",
3493 "\n",
3494 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
3495 " if (msg['mode'] === 'PAN') {\n",
3496 " fig.buttons['Pan'].classList.add('active');\n",
3497 " fig.buttons['Zoom'].classList.remove('active');\n",
3498 " } else if (msg['mode'] === 'ZOOM') {\n",
3499 " fig.buttons['Pan'].classList.remove('active');\n",
3500 " fig.buttons['Zoom'].classList.add('active');\n",
3501 " } else {\n",
3502 " fig.buttons['Pan'].classList.remove('active');\n",
3503 " fig.buttons['Zoom'].classList.remove('active');\n",
3504 " }\n",
3505 "};\n",
3506 "\n",
3507 "mpl.figure.prototype.updated_canvas_event = function () {\n",
3508 " // Called whenever the canvas gets updated.\n",
3509 " this.send_message('ack', {});\n",
3510 "};\n",
3511 "\n",
3512 "// A function to construct a web socket function for onmessage handling.\n",
3513 "// Called in the figure constructor.\n",
3514 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
3515 " return function socket_on_message(evt) {\n",
3516 " if (evt.data instanceof Blob) {\n",
3517 " /* FIXME: We get \"Resource interpreted as Image but\n",
3518 " * transferred with MIME type text/plain:\" errors on\n",
3519 " * Chrome. But how to set the MIME type? It doesn't seem\n",
3520 " * to be part of the websocket stream */\n",
3521 " evt.data.type = 'image/png';\n",
3522 "\n",
3523 " /* Free the memory for the previous frames */\n",
3524 " if (fig.imageObj.src) {\n",
3525 " (window.URL || window.webkitURL).revokeObjectURL(\n",
3526 " fig.imageObj.src\n",
3527 " );\n",
3528 " }\n",
3529 "\n",
3530 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
3531 " evt.data\n",
3532 " );\n",
3533 " fig.updated_canvas_event();\n",
3534 " fig.waiting = false;\n",
3535 " return;\n",
3536 " } else if (\n",
3537 " typeof evt.data === 'string' &&\n",
3538 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
3539 " ) {\n",
3540 " fig.imageObj.src = evt.data;\n",
3541 " fig.updated_canvas_event();\n",
3542 " fig.waiting = false;\n",
3543 " return;\n",
3544 " }\n",
3545 "\n",
3546 " var msg = JSON.parse(evt.data);\n",
3547 " var msg_type = msg['type'];\n",
3548 "\n",
3549 " // Call the \"handle_{type}\" callback, which takes\n",
3550 " // the figure and JSON message as its only arguments.\n",
3551 " try {\n",
3552 " var callback = fig['handle_' + msg_type];\n",
3553 " } catch (e) {\n",
3554 " console.log(\n",
3555 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
3556 " msg\n",
3557 " );\n",
3558 " return;\n",
3559 " }\n",
3560 "\n",
3561 " if (callback) {\n",
3562 " try {\n",
3563 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
3564 " callback(fig, msg);\n",
3565 " } catch (e) {\n",
3566 " console.log(\n",
3567 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
3568 " e,\n",
3569 " e.stack,\n",
3570 " msg\n",
3571 " );\n",
3572 " }\n",
3573 " }\n",
3574 " };\n",
3575 "};\n",
3576 "\n",
3577 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
3578 "mpl.findpos = function (e) {\n",
3579 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
3580 " var targ;\n",
3581 " if (!e) {\n",
3582 " e = window.event;\n",
3583 " }\n",
3584 " if (e.target) {\n",
3585 " targ = e.target;\n",
3586 " } else if (e.srcElement) {\n",
3587 " targ = e.srcElement;\n",
3588 " }\n",
3589 " if (targ.nodeType === 3) {\n",
3590 " // defeat Safari bug\n",
3591 " targ = targ.parentNode;\n",
3592 " }\n",
3593 "\n",
3594 " // pageX,Y are the mouse positions relative to the document\n",
3595 " var boundingRect = targ.getBoundingClientRect();\n",
3596 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
3597 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
3598 "\n",
3599 " return { x: x, y: y };\n",
3600 "};\n",
3601 "\n",
3602 "/*\n",
3603 " * return a copy of an object with only non-object keys\n",
3604 " * we need this to avoid circular references\n",
3605 " * http://stackoverflow.com/a/24161582/3208463\n",
3606 " */\n",
3607 "function simpleKeys(original) {\n",
3608 " return Object.keys(original).reduce(function (obj, key) {\n",
3609 " if (typeof original[key] !== 'object') {\n",
3610 " obj[key] = original[key];\n",
3611 " }\n",
3612 " return obj;\n",
3613 " }, {});\n",
3614 "}\n",
3615 "\n",
3616 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
3617 " var canvas_pos = mpl.findpos(event);\n",
3618 "\n",
3619 " if (name === 'button_press') {\n",
3620 " this.canvas.focus();\n",
3621 " this.canvas_div.focus();\n",
3622 " }\n",
3623 "\n",
3624 " var x = canvas_pos.x * this.ratio;\n",
3625 " var y = canvas_pos.y * this.ratio;\n",
3626 "\n",
3627 " this.send_message(name, {\n",
3628 " x: x,\n",
3629 " y: y,\n",
3630 " button: event.button,\n",
3631 " step: event.step,\n",
3632 " guiEvent: simpleKeys(event),\n",
3633 " });\n",
3634 "\n",
3635 " /* This prevents the web browser from automatically changing to\n",
3636 " * the text insertion cursor when the button is pressed. We want\n",
3637 " * to control all of the cursor setting manually through the\n",
3638 " * 'cursor' event from matplotlib */\n",
3639 " event.preventDefault();\n",
3640 " return false;\n",
3641 "};\n",
3642 "\n",
3643 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
3644 " // Handle any extra behaviour associated with a key event\n",
3645 "};\n",
3646 "\n",
3647 "mpl.figure.prototype.key_event = function (event, name) {\n",
3648 " // Prevent repeat events\n",
3649 " if (name === 'key_press') {\n",
3650 " if (event.which === this._key) {\n",
3651 " return;\n",
3652 " } else {\n",
3653 " this._key = event.which;\n",
3654 " }\n",
3655 " }\n",
3656 " if (name === 'key_release') {\n",
3657 " this._key = null;\n",
3658 " }\n",
3659 "\n",
3660 " var value = '';\n",
3661 " if (event.ctrlKey && event.which !== 17) {\n",
3662 " value += 'ctrl+';\n",
3663 " }\n",
3664 " if (event.altKey && event.which !== 18) {\n",
3665 " value += 'alt+';\n",
3666 " }\n",
3667 " if (event.shiftKey && event.which !== 16) {\n",
3668 " value += 'shift+';\n",
3669 " }\n",
3670 "\n",
3671 " value += 'k';\n",
3672 " value += event.which.toString();\n",
3673 "\n",
3674 " this._key_event_extra(event, name);\n",
3675 "\n",
3676 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
3677 " return false;\n",
3678 "};\n",
3679 "\n",
3680 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
3681 " if (name === 'download') {\n",
3682 " this.handle_save(this, null);\n",
3683 " } else {\n",
3684 " this.send_message('toolbar_button', { name: name });\n",
3685 " }\n",
3686 "};\n",
3687 "\n",
3688 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
3689 " this.message.textContent = tooltip;\n",
3690 "};\n",
3691 "\n",
3692 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
3693 "// prettier-ignore\n",
3694 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
3695 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
3696 "\n",
3697 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
3698 "\n",
3699 "mpl.default_extension = \"png\";/* global mpl */\n",
3700 "\n",
3701 "var comm_websocket_adapter = function (comm) {\n",
3702 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
3703 " // object with the appropriate methods. Currently this is a non binary\n",
3704 " // socket, so there is still some room for performance tuning.\n",
3705 " var ws = {};\n",
3706 "\n",
3707 " ws.close = function () {\n",
3708 " comm.close();\n",
3709 " };\n",
3710 " ws.send = function (m) {\n",
3711 " //console.log('sending', m);\n",
3712 " comm.send(m);\n",
3713 " };\n",
3714 " // Register the callback with on_msg.\n",
3715 " comm.on_msg(function (msg) {\n",
3716 " //console.log('receiving', msg['content']['data'], msg);\n",
3717 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
3718 " ws.onmessage(msg['content']['data']);\n",
3719 " });\n",
3720 " return ws;\n",
3721 "};\n",
3722 "\n",
3723 "mpl.mpl_figure_comm = function (comm, msg) {\n",
3724 " // This is the function which gets called when the mpl process\n",
3725 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
3726 "\n",
3727 " var id = msg.content.data.id;\n",
3728 " // Get hold of the div created by the display call when the Comm\n",
3729 " // socket was opened in Python.\n",
3730 " var element = document.getElementById(id);\n",
3731 " var ws_proxy = comm_websocket_adapter(comm);\n",
3732 "\n",
3733 " function ondownload(figure, _format) {\n",
3734 " window.open(figure.canvas.toDataURL());\n",
3735 " }\n",
3736 "\n",
3737 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
3738 "\n",
3739 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
3740 " // web socket which is closed, not our websocket->open comm proxy.\n",
3741 " ws_proxy.onopen();\n",
3742 "\n",
3743 " fig.parent_element = element;\n",
3744 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
3745 " if (!fig.cell_info) {\n",
3746 " console.error('Failed to find cell for figure', id, fig);\n",
3747 " return;\n",
3748 " }\n",
3749 " fig.cell_info[0].output_area.element.on(\n",
3750 " 'cleared',\n",
3751 " { fig: fig },\n",
3752 " fig._remove_fig_handler\n",
3753 " );\n",
3754 "};\n",
3755 "\n",
3756 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
3757 " var width = fig.canvas.width / fig.ratio;\n",
3758 " fig.cell_info[0].output_area.element.off(\n",
3759 " 'cleared',\n",
3760 " fig._remove_fig_handler\n",
3761 " );\n",
3762 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
3763 "\n",
3764 " // Update the output cell to use the data from the current canvas.\n",
3765 " fig.push_to_output();\n",
3766 " var dataURL = fig.canvas.toDataURL();\n",
3767 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
3768 " // the notebook keyboard shortcuts fail.\n",
3769 " IPython.keyboard_manager.enable();\n",
3770 " fig.parent_element.innerHTML =\n",
3771 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
3772 " fig.close_ws(fig, msg);\n",
3773 "};\n",
3774 "\n",
3775 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
3776 " fig.send_message('closing', msg);\n",
3777 " // fig.ws.close()\n",
3778 "};\n",
3779 "\n",
3780 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
3781 " // Turn the data on the canvas into data in the output cell.\n",
3782 " var width = this.canvas.width / this.ratio;\n",
3783 " var dataURL = this.canvas.toDataURL();\n",
3784 " this.cell_info[1]['text/html'] =\n",
3785 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
3786 "};\n",
3787 "\n",
3788 "mpl.figure.prototype.updated_canvas_event = function () {\n",
3789 " // Tell IPython that the notebook contents must change.\n",
3790 " IPython.notebook.set_dirty(true);\n",
3791 " this.send_message('ack', {});\n",
3792 " var fig = this;\n",
3793 " // Wait a second, then push the new image to the DOM so\n",
3794 " // that it is saved nicely (might be nice to debounce this).\n",
3795 " setTimeout(function () {\n",
3796 " fig.push_to_output();\n",
3797 " }, 1000);\n",
3798 "};\n",
3799 "\n",
3800 "mpl.figure.prototype._init_toolbar = function () {\n",
3801 " var fig = this;\n",
3802 "\n",
3803 " var toolbar = document.createElement('div');\n",
3804 " toolbar.classList = 'btn-toolbar';\n",
3805 " this.root.appendChild(toolbar);\n",
3806 "\n",
3807 " function on_click_closure(name) {\n",
3808 " return function (_event) {\n",
3809 " return fig.toolbar_button_onclick(name);\n",
3810 " };\n",
3811 " }\n",
3812 "\n",
3813 " function on_mouseover_closure(tooltip) {\n",
3814 " return function (event) {\n",
3815 " if (!event.currentTarget.disabled) {\n",
3816 " return fig.toolbar_button_onmouseover(tooltip);\n",
3817 " }\n",
3818 " };\n",
3819 " }\n",
3820 "\n",
3821 " fig.buttons = {};\n",
3822 " var buttonGroup = document.createElement('div');\n",
3823 " buttonGroup.classList = 'btn-group';\n",
3824 " var button;\n",
3825 " for (var toolbar_ind in mpl.toolbar_items) {\n",
3826 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
3827 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
3828 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
3829 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
3830 "\n",
3831 " if (!name) {\n",
3832 " /* Instead of a spacer, we start a new button group. */\n",
3833 " if (buttonGroup.hasChildNodes()) {\n",
3834 " toolbar.appendChild(buttonGroup);\n",
3835 " }\n",
3836 " buttonGroup = document.createElement('div');\n",
3837 " buttonGroup.classList = 'btn-group';\n",
3838 " continue;\n",
3839 " }\n",
3840 "\n",
3841 " button = fig.buttons[name] = document.createElement('button');\n",
3842 " button.classList = 'btn btn-default';\n",
3843 " button.href = '#';\n",
3844 " button.title = name;\n",
3845 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
3846 " button.addEventListener('click', on_click_closure(method_name));\n",
3847 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
3848 " buttonGroup.appendChild(button);\n",
3849 " }\n",
3850 "\n",
3851 " if (buttonGroup.hasChildNodes()) {\n",
3852 " toolbar.appendChild(buttonGroup);\n",
3853 " }\n",
3854 "\n",
3855 " // Add the status bar.\n",
3856 " var status_bar = document.createElement('span');\n",
3857 " status_bar.classList = 'mpl-message pull-right';\n",
3858 " toolbar.appendChild(status_bar);\n",
3859 " this.message = status_bar;\n",
3860 "\n",
3861 " // Add the close button to the window.\n",
3862 " var buttongrp = document.createElement('div');\n",
3863 " buttongrp.classList = 'btn-group inline pull-right';\n",
3864 " button = document.createElement('button');\n",
3865 " button.classList = 'btn btn-mini btn-primary';\n",
3866 " button.href = '#';\n",
3867 " button.title = 'Stop Interaction';\n",
3868 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
3869 " button.addEventListener('click', function (_evt) {\n",
3870 " fig.handle_close(fig, {});\n",
3871 " });\n",
3872 " button.addEventListener(\n",
3873 " 'mouseover',\n",
3874 " on_mouseover_closure('Stop Interaction')\n",
3875 " );\n",
3876 " buttongrp.appendChild(button);\n",
3877 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
3878 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
3879 "};\n",
3880 "\n",
3881 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
3882 " var fig = event.data.fig;\n",
3883 " if (event.target !== this) {\n",
3884 " // Ignore bubbled events from children.\n",
3885 " return;\n",
3886 " }\n",
3887 " fig.close_ws(fig, {});\n",
3888 "};\n",
3889 "\n",
3890 "mpl.figure.prototype._root_extra_style = function (el) {\n",
3891 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
3892 "};\n",
3893 "\n",
3894 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
3895 " // this is important to make the div 'focusable\n",
3896 " el.setAttribute('tabindex', 0);\n",
3897 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
3898 " // off when our div gets focus\n",
3899 "\n",
3900 " // location in version 3\n",
3901 " if (IPython.notebook.keyboard_manager) {\n",
3902 " IPython.notebook.keyboard_manager.register_events(el);\n",
3903 " } else {\n",
3904 " // location in version 2\n",
3905 " IPython.keyboard_manager.register_events(el);\n",
3906 " }\n",
3907 "};\n",
3908 "\n",
3909 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
3910 " var manager = IPython.notebook.keyboard_manager;\n",
3911 " if (!manager) {\n",
3912 " manager = IPython.keyboard_manager;\n",
3913 " }\n",
3914 "\n",
3915 " // Check for shift+enter\n",
3916 " if (event.shiftKey && event.which === 13) {\n",
3917 " this.canvas_div.blur();\n",
3918 " // select the cell after this one\n",
3919 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
3920 " IPython.notebook.select(index + 1);\n",
3921 " }\n",
3922 "};\n",
3923 "\n",
3924 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
3925 " fig.ondownload(fig, null);\n",
3926 "};\n",
3927 "\n",
3928 "mpl.find_output_cell = function (html_output) {\n",
3929 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
3930 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
3931 " // IPython event is triggered only after the cells have been serialised, which for\n",
3932 " // our purposes (turning an active figure into a static one), is too late.\n",
3933 " var cells = IPython.notebook.get_cells();\n",
3934 " var ncells = cells.length;\n",
3935 " for (var i = 0; i < ncells; i++) {\n",
3936 " var cell = cells[i];\n",
3937 " if (cell.cell_type === 'code') {\n",
3938 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
3939 " var data = cell.output_area.outputs[j];\n",
3940 " if (data.data) {\n",
3941 " // IPython >= 3 moved mimebundle to data attribute of output\n",
3942 " data = data.data;\n",
3943 " }\n",
3944 " if (data['text/html'] === html_output) {\n",
3945 " return [cell, data, j];\n",
3946 " }\n",
3947 " }\n",
3948 " }\n",
3949 " }\n",
3950 "};\n",
3951 "\n",
3952 "// Register the function which deals with the matplotlib target/channel.\n",
3953 "// The kernel may be null if the page has been refreshed.\n",
3954 "if (IPython.notebook.kernel !== null) {\n",
3955 " IPython.notebook.kernel.comm_manager.register_target(\n",
3956 " 'matplotlib',\n",
3957 " mpl.mpl_figure_comm\n",
3958 " );\n",
3959 "}\n"
3960 ],
3961 "text/plain": [
3962 "<IPython.core.display.Javascript object>"
3963 ]
3964 },
3965 "metadata": {},
3966 "output_type": "display_data"
3967 },
3968 {
3969 "data": {
3970 "text/html": [
3971 "<div id='fdd106db-abc6-48fd-9057-2a7436dda349'></div>"
3972 ],
3973 "text/plain": [
3974 "<IPython.core.display.HTML object>"
3975 ]
3976 },
3977 "metadata": {},
3978 "output_type": "display_data"
3979 }
3980 ],
3981 "source": [
3982 "from sklearn.datasets import make_classification, make_blobs\n",
3983 "from matplotlib.colors import ListedColormap\n",
3984 "from sklearn.datasets import load_breast_cancer\n",
3985 "from adspy_shared_utilities import load_crime_dataset\n",
3986 "\n",
3987 "cmap_bold = ListedColormap(['#FFFF00', '#00FF00', '#0000FF','#000000'])\n",
3988 "\n",
3989 "\n",
3990 "# synthetic dataset for simple regression\n",
3991 "from sklearn.datasets import make_regression\n",
3992 "plt.figure()\n",
3993 "plt.title('Sample regression problem with one input variable')\n",
3994 "X_R1, y_R1 = make_regression(n_samples = 100, n_features=1,\n",
3995 " n_informative=1, bias = 150.0,\n",
3996 " noise = 30, random_state=0)\n",
3997 "plt.scatter(X_R1, y_R1, marker= 'o', s=50)\n",
3998 "plt.show()\n",
3999 "\n",
4000 "\n",
4001 "# synthetic dataset for more complex regression\n",
4002 "from sklearn.datasets import make_friedman1\n",
4003 "plt.figure()\n",
4004 "plt.title('Complex regression problem with one input variable')\n",
4005 "X_F1, y_F1 = make_friedman1(n_samples = 100,\n",
4006 " n_features = 7, random_state=0)\n",
4007 "\n",
4008 "plt.scatter(X_F1[:, 2], y_F1, marker= 'o', s=50)\n",
4009 "plt.show()\n",
4010 "\n",
4011 "# synthetic dataset for classification (binary) \n",
4012 "plt.figure()\n",
4013 "plt.title('Sample binary classification problem with two informative features')\n",
4014 "X_C2, y_C2 = make_classification(n_samples = 100, n_features=2,\n",
4015 " n_redundant=0, n_informative=2,\n",
4016 " n_clusters_per_class=1, flip_y = 0.1,\n",
4017 " class_sep = 0.5, random_state=0)\n",
4018 "plt.scatter(X_C2[:, 0], X_C2[:, 1], c=y_C2,\n",
4019 " marker= 'o', s=50, cmap=cmap_bold)\n",
4020 "plt.show()\n",
4021 "\n",
4022 "\n",
4023 "# more difficult synthetic dataset for classification (binary) \n",
4024 "# with classes that are not linearly separable\n",
4025 "X_D2, y_D2 = make_blobs(n_samples = 100, n_features = 2, centers = 8,\n",
4026 " cluster_std = 1.3, random_state = 4)\n",
4027 "y_D2 = y_D2 % 2\n",
4028 "plt.figure()\n",
4029 "plt.title('Sample binary classification problem with non-linearly separable classes')\n",
4030 "plt.scatter(X_D2[:,0], X_D2[:,1], c=y_D2,\n",
4031 " marker= 'o', s=50, cmap=cmap_bold)\n",
4032 "plt.show()\n",
4033 "\n",
4034 "\n",
4035 "# Breast cancer dataset for classification\n",
4036 "cancer = load_breast_cancer()\n",
4037 "(X_cancer, y_cancer) = load_breast_cancer(return_X_y = True)\n",
4038 "\n",
4039 "\n",
4040 "# Communities and Crime dataset\n",
4041 "#(X_crime, y_crime) = load_crime_dataset()"
4042 ]
4043 },
4044 {
4045 "cell_type": "markdown",
4046 "metadata": {},
4047 "source": [
4048 "## K-Nearest Neighbors"
4049 ]
4050 },
4051 {
4052 "cell_type": "markdown",
4053 "metadata": {},
4054 "source": [
4055 "### Classification"
4056 ]
4057 },
4058 {
4059 "cell_type": "code",
4060 "execution_count": 3,
4061 "metadata": {
4062 "scrolled": false
4063 },
4064 "outputs": [
4065 {
4066 "data": {
4067 "application/javascript": [
4068 "/* Put everything inside the global mpl namespace */\n",
4069 "/* global mpl */\n",
4070 "window.mpl = {};\n",
4071 "\n",
4072 "mpl.get_websocket_type = function () {\n",
4073 " if (typeof WebSocket !== 'undefined') {\n",
4074 " return WebSocket;\n",
4075 " } else if (typeof MozWebSocket !== 'undefined') {\n",
4076 " return MozWebSocket;\n",
4077 " } else {\n",
4078 " alert(\n",
4079 " 'Your browser does not have WebSocket support. ' +\n",
4080 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
4081 " 'Firefox 4 and 5 are also supported but you ' +\n",
4082 " 'have to enable WebSockets in about:config.'\n",
4083 " );\n",
4084 " }\n",
4085 "};\n",
4086 "\n",
4087 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
4088 " this.id = figure_id;\n",
4089 "\n",
4090 " this.ws = websocket;\n",
4091 "\n",
4092 " this.supports_binary = this.ws.binaryType !== undefined;\n",
4093 "\n",
4094 " if (!this.supports_binary) {\n",
4095 " var warnings = document.getElementById('mpl-warnings');\n",
4096 " if (warnings) {\n",
4097 " warnings.style.display = 'block';\n",
4098 " warnings.textContent =\n",
4099 " 'This browser does not support binary websocket messages. ' +\n",
4100 " 'Performance may be slow.';\n",
4101 " }\n",
4102 " }\n",
4103 "\n",
4104 " this.imageObj = new Image();\n",
4105 "\n",
4106 " this.context = undefined;\n",
4107 " this.message = undefined;\n",
4108 " this.canvas = undefined;\n",
4109 " this.rubberband_canvas = undefined;\n",
4110 " this.rubberband_context = undefined;\n",
4111 " this.format_dropdown = undefined;\n",
4112 "\n",
4113 " this.image_mode = 'full';\n",
4114 "\n",
4115 " this.root = document.createElement('div');\n",
4116 " this.root.setAttribute('style', 'display: inline-block');\n",
4117 " this._root_extra_style(this.root);\n",
4118 "\n",
4119 " parent_element.appendChild(this.root);\n",
4120 "\n",
4121 " this._init_header(this);\n",
4122 " this._init_canvas(this);\n",
4123 " this._init_toolbar(this);\n",
4124 "\n",
4125 " var fig = this;\n",
4126 "\n",
4127 " this.waiting = false;\n",
4128 "\n",
4129 " this.ws.onopen = function () {\n",
4130 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
4131 " fig.send_message('send_image_mode', {});\n",
4132 " if (fig.ratio !== 1) {\n",
4133 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
4134 " }\n",
4135 " fig.send_message('refresh', {});\n",
4136 " };\n",
4137 "\n",
4138 " this.imageObj.onload = function () {\n",
4139 " if (fig.image_mode === 'full') {\n",
4140 " // Full images could contain transparency (where diff images\n",
4141 " // almost always do), so we need to clear the canvas so that\n",
4142 " // there is no ghosting.\n",
4143 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
4144 " }\n",
4145 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
4146 " };\n",
4147 "\n",
4148 " this.imageObj.onunload = function () {\n",
4149 " fig.ws.close();\n",
4150 " };\n",
4151 "\n",
4152 " this.ws.onmessage = this._make_on_message_function(this);\n",
4153 "\n",
4154 " this.ondownload = ondownload;\n",
4155 "};\n",
4156 "\n",
4157 "mpl.figure.prototype._init_header = function () {\n",
4158 " var titlebar = document.createElement('div');\n",
4159 " titlebar.classList =\n",
4160 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
4161 " var titletext = document.createElement('div');\n",
4162 " titletext.classList = 'ui-dialog-title';\n",
4163 " titletext.setAttribute(\n",
4164 " 'style',\n",
4165 " 'width: 100%; text-align: center; padding: 3px;'\n",
4166 " );\n",
4167 " titlebar.appendChild(titletext);\n",
4168 " this.root.appendChild(titlebar);\n",
4169 " this.header = titletext;\n",
4170 "};\n",
4171 "\n",
4172 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
4173 "\n",
4174 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
4175 "\n",
4176 "mpl.figure.prototype._init_canvas = function () {\n",
4177 " var fig = this;\n",
4178 "\n",
4179 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
4180 " canvas_div.setAttribute(\n",
4181 " 'style',\n",
4182 " 'border: 1px solid #ddd;' +\n",
4183 " 'box-sizing: content-box;' +\n",
4184 " 'clear: both;' +\n",
4185 " 'min-height: 1px;' +\n",
4186 " 'min-width: 1px;' +\n",
4187 " 'outline: 0;' +\n",
4188 " 'overflow: hidden;' +\n",
4189 " 'position: relative;' +\n",
4190 " 'resize: both;'\n",
4191 " );\n",
4192 "\n",
4193 " function on_keyboard_event_closure(name) {\n",
4194 " return function (event) {\n",
4195 " return fig.key_event(event, name);\n",
4196 " };\n",
4197 " }\n",
4198 "\n",
4199 " canvas_div.addEventListener(\n",
4200 " 'keydown',\n",
4201 " on_keyboard_event_closure('key_press')\n",
4202 " );\n",
4203 " canvas_div.addEventListener(\n",
4204 " 'keyup',\n",
4205 " on_keyboard_event_closure('key_release')\n",
4206 " );\n",
4207 "\n",
4208 " this._canvas_extra_style(canvas_div);\n",
4209 " this.root.appendChild(canvas_div);\n",
4210 "\n",
4211 " var canvas = (this.canvas = document.createElement('canvas'));\n",
4212 " canvas.classList.add('mpl-canvas');\n",
4213 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
4214 "\n",
4215 " this.context = canvas.getContext('2d');\n",
4216 "\n",
4217 " var backingStore =\n",
4218 " this.context.backingStorePixelRatio ||\n",
4219 " this.context.webkitBackingStorePixelRatio ||\n",
4220 " this.context.mozBackingStorePixelRatio ||\n",
4221 " this.context.msBackingStorePixelRatio ||\n",
4222 " this.context.oBackingStorePixelRatio ||\n",
4223 " this.context.backingStorePixelRatio ||\n",
4224 " 1;\n",
4225 "\n",
4226 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
4227 "\n",
4228 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
4229 " 'canvas'\n",
4230 " ));\n",
4231 " rubberband_canvas.setAttribute(\n",
4232 " 'style',\n",
4233 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
4234 " );\n",
4235 "\n",
4236 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
4237 " if (this.ResizeObserver === undefined) {\n",
4238 " if (window.ResizeObserver !== undefined) {\n",
4239 " this.ResizeObserver = window.ResizeObserver;\n",
4240 " } else {\n",
4241 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
4242 " this.ResizeObserver = obs.ResizeObserver;\n",
4243 " }\n",
4244 " }\n",
4245 "\n",
4246 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
4247 " var nentries = entries.length;\n",
4248 " for (var i = 0; i < nentries; i++) {\n",
4249 " var entry = entries[i];\n",
4250 " var width, height;\n",
4251 " if (entry.contentBoxSize) {\n",
4252 " if (entry.contentBoxSize instanceof Array) {\n",
4253 " // Chrome 84 implements new version of spec.\n",
4254 " width = entry.contentBoxSize[0].inlineSize;\n",
4255 " height = entry.contentBoxSize[0].blockSize;\n",
4256 " } else {\n",
4257 " // Firefox implements old version of spec.\n",
4258 " width = entry.contentBoxSize.inlineSize;\n",
4259 " height = entry.contentBoxSize.blockSize;\n",
4260 " }\n",
4261 " } else {\n",
4262 " // Chrome <84 implements even older version of spec.\n",
4263 " width = entry.contentRect.width;\n",
4264 " height = entry.contentRect.height;\n",
4265 " }\n",
4266 "\n",
4267 " // Keep the size of the canvas and rubber band canvas in sync with\n",
4268 " // the canvas container.\n",
4269 " if (entry.devicePixelContentBoxSize) {\n",
4270 " // Chrome 84 implements new version of spec.\n",
4271 " canvas.setAttribute(\n",
4272 " 'width',\n",
4273 " entry.devicePixelContentBoxSize[0].inlineSize\n",
4274 " );\n",
4275 " canvas.setAttribute(\n",
4276 " 'height',\n",
4277 " entry.devicePixelContentBoxSize[0].blockSize\n",
4278 " );\n",
4279 " } else {\n",
4280 " canvas.setAttribute('width', width * fig.ratio);\n",
4281 " canvas.setAttribute('height', height * fig.ratio);\n",
4282 " }\n",
4283 " canvas.setAttribute(\n",
4284 " 'style',\n",
4285 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
4286 " );\n",
4287 "\n",
4288 " rubberband_canvas.setAttribute('width', width);\n",
4289 " rubberband_canvas.setAttribute('height', height);\n",
4290 "\n",
4291 " // And update the size in Python. We ignore the initial 0/0 size\n",
4292 " // that occurs as the element is placed into the DOM, which should\n",
4293 " // otherwise not happen due to the minimum size styling.\n",
4294 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
4295 " fig.request_resize(width, height);\n",
4296 " }\n",
4297 " }\n",
4298 " });\n",
4299 " this.resizeObserverInstance.observe(canvas_div);\n",
4300 "\n",
4301 " function on_mouse_event_closure(name) {\n",
4302 " return function (event) {\n",
4303 " return fig.mouse_event(event, name);\n",
4304 " };\n",
4305 " }\n",
4306 "\n",
4307 " rubberband_canvas.addEventListener(\n",
4308 " 'mousedown',\n",
4309 " on_mouse_event_closure('button_press')\n",
4310 " );\n",
4311 " rubberband_canvas.addEventListener(\n",
4312 " 'mouseup',\n",
4313 " on_mouse_event_closure('button_release')\n",
4314 " );\n",
4315 " // Throttle sequential mouse events to 1 every 20ms.\n",
4316 " rubberband_canvas.addEventListener(\n",
4317 " 'mousemove',\n",
4318 " on_mouse_event_closure('motion_notify')\n",
4319 " );\n",
4320 "\n",
4321 " rubberband_canvas.addEventListener(\n",
4322 " 'mouseenter',\n",
4323 " on_mouse_event_closure('figure_enter')\n",
4324 " );\n",
4325 " rubberband_canvas.addEventListener(\n",
4326 " 'mouseleave',\n",
4327 " on_mouse_event_closure('figure_leave')\n",
4328 " );\n",
4329 "\n",
4330 " canvas_div.addEventListener('wheel', function (event) {\n",
4331 " if (event.deltaY < 0) {\n",
4332 " event.step = 1;\n",
4333 " } else {\n",
4334 " event.step = -1;\n",
4335 " }\n",
4336 " on_mouse_event_closure('scroll')(event);\n",
4337 " });\n",
4338 "\n",
4339 " canvas_div.appendChild(canvas);\n",
4340 " canvas_div.appendChild(rubberband_canvas);\n",
4341 "\n",
4342 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
4343 " this.rubberband_context.strokeStyle = '#000000';\n",
4344 "\n",
4345 " this._resize_canvas = function (width, height, forward) {\n",
4346 " if (forward) {\n",
4347 " canvas_div.style.width = width + 'px';\n",
4348 " canvas_div.style.height = height + 'px';\n",
4349 " }\n",
4350 " };\n",
4351 "\n",
4352 " // Disable right mouse context menu.\n",
4353 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
4354 " event.preventDefault();\n",
4355 " return false;\n",
4356 " });\n",
4357 "\n",
4358 " function set_focus() {\n",
4359 " canvas.focus();\n",
4360 " canvas_div.focus();\n",
4361 " }\n",
4362 "\n",
4363 " window.setTimeout(set_focus, 100);\n",
4364 "};\n",
4365 "\n",
4366 "mpl.figure.prototype._init_toolbar = function () {\n",
4367 " var fig = this;\n",
4368 "\n",
4369 " var toolbar = document.createElement('div');\n",
4370 " toolbar.classList = 'mpl-toolbar';\n",
4371 " this.root.appendChild(toolbar);\n",
4372 "\n",
4373 " function on_click_closure(name) {\n",
4374 " return function (_event) {\n",
4375 " return fig.toolbar_button_onclick(name);\n",
4376 " };\n",
4377 " }\n",
4378 "\n",
4379 " function on_mouseover_closure(tooltip) {\n",
4380 " return function (event) {\n",
4381 " if (!event.currentTarget.disabled) {\n",
4382 " return fig.toolbar_button_onmouseover(tooltip);\n",
4383 " }\n",
4384 " };\n",
4385 " }\n",
4386 "\n",
4387 " fig.buttons = {};\n",
4388 " var buttonGroup = document.createElement('div');\n",
4389 " buttonGroup.classList = 'mpl-button-group';\n",
4390 " for (var toolbar_ind in mpl.toolbar_items) {\n",
4391 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
4392 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
4393 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
4394 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
4395 "\n",
4396 " if (!name) {\n",
4397 " /* Instead of a spacer, we start a new button group. */\n",
4398 " if (buttonGroup.hasChildNodes()) {\n",
4399 " toolbar.appendChild(buttonGroup);\n",
4400 " }\n",
4401 " buttonGroup = document.createElement('div');\n",
4402 " buttonGroup.classList = 'mpl-button-group';\n",
4403 " continue;\n",
4404 " }\n",
4405 "\n",
4406 " var button = (fig.buttons[name] = document.createElement('button'));\n",
4407 " button.classList = 'mpl-widget';\n",
4408 " button.setAttribute('role', 'button');\n",
4409 " button.setAttribute('aria-disabled', 'false');\n",
4410 " button.addEventListener('click', on_click_closure(method_name));\n",
4411 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
4412 "\n",
4413 " var icon_img = document.createElement('img');\n",
4414 " icon_img.src = '_images/' + image + '.png';\n",
4415 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
4416 " icon_img.alt = tooltip;\n",
4417 " button.appendChild(icon_img);\n",
4418 "\n",
4419 " buttonGroup.appendChild(button);\n",
4420 " }\n",
4421 "\n",
4422 " if (buttonGroup.hasChildNodes()) {\n",
4423 " toolbar.appendChild(buttonGroup);\n",
4424 " }\n",
4425 "\n",
4426 " var fmt_picker = document.createElement('select');\n",
4427 " fmt_picker.classList = 'mpl-widget';\n",
4428 " toolbar.appendChild(fmt_picker);\n",
4429 " this.format_dropdown = fmt_picker;\n",
4430 "\n",
4431 " for (var ind in mpl.extensions) {\n",
4432 " var fmt = mpl.extensions[ind];\n",
4433 " var option = document.createElement('option');\n",
4434 " option.selected = fmt === mpl.default_extension;\n",
4435 " option.innerHTML = fmt;\n",
4436 " fmt_picker.appendChild(option);\n",
4437 " }\n",
4438 "\n",
4439 " var status_bar = document.createElement('span');\n",
4440 " status_bar.classList = 'mpl-message';\n",
4441 " toolbar.appendChild(status_bar);\n",
4442 " this.message = status_bar;\n",
4443 "};\n",
4444 "\n",
4445 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
4446 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
4447 " // which will in turn request a refresh of the image.\n",
4448 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
4449 "};\n",
4450 "\n",
4451 "mpl.figure.prototype.send_message = function (type, properties) {\n",
4452 " properties['type'] = type;\n",
4453 " properties['figure_id'] = this.id;\n",
4454 " this.ws.send(JSON.stringify(properties));\n",
4455 "};\n",
4456 "\n",
4457 "mpl.figure.prototype.send_draw_message = function () {\n",
4458 " if (!this.waiting) {\n",
4459 " this.waiting = true;\n",
4460 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
4461 " }\n",
4462 "};\n",
4463 "\n",
4464 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
4465 " var format_dropdown = fig.format_dropdown;\n",
4466 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
4467 " fig.ondownload(fig, format);\n",
4468 "};\n",
4469 "\n",
4470 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
4471 " var size = msg['size'];\n",
4472 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
4473 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
4474 " fig.send_message('refresh', {});\n",
4475 " }\n",
4476 "};\n",
4477 "\n",
4478 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
4479 " var x0 = msg['x0'] / fig.ratio;\n",
4480 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
4481 " var x1 = msg['x1'] / fig.ratio;\n",
4482 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
4483 " x0 = Math.floor(x0) + 0.5;\n",
4484 " y0 = Math.floor(y0) + 0.5;\n",
4485 " x1 = Math.floor(x1) + 0.5;\n",
4486 " y1 = Math.floor(y1) + 0.5;\n",
4487 " var min_x = Math.min(x0, x1);\n",
4488 " var min_y = Math.min(y0, y1);\n",
4489 " var width = Math.abs(x1 - x0);\n",
4490 " var height = Math.abs(y1 - y0);\n",
4491 "\n",
4492 " fig.rubberband_context.clearRect(\n",
4493 " 0,\n",
4494 " 0,\n",
4495 " fig.canvas.width / fig.ratio,\n",
4496 " fig.canvas.height / fig.ratio\n",
4497 " );\n",
4498 "\n",
4499 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
4500 "};\n",
4501 "\n",
4502 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
4503 " // Updates the figure title.\n",
4504 " fig.header.textContent = msg['label'];\n",
4505 "};\n",
4506 "\n",
4507 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
4508 " var cursor = msg['cursor'];\n",
4509 " switch (cursor) {\n",
4510 " case 0:\n",
4511 " cursor = 'pointer';\n",
4512 " break;\n",
4513 " case 1:\n",
4514 " cursor = 'default';\n",
4515 " break;\n",
4516 " case 2:\n",
4517 " cursor = 'crosshair';\n",
4518 " break;\n",
4519 " case 3:\n",
4520 " cursor = 'move';\n",
4521 " break;\n",
4522 " }\n",
4523 " fig.rubberband_canvas.style.cursor = cursor;\n",
4524 "};\n",
4525 "\n",
4526 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
4527 " fig.message.textContent = msg['message'];\n",
4528 "};\n",
4529 "\n",
4530 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
4531 " // Request the server to send over a new figure.\n",
4532 " fig.send_draw_message();\n",
4533 "};\n",
4534 "\n",
4535 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
4536 " fig.image_mode = msg['mode'];\n",
4537 "};\n",
4538 "\n",
4539 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
4540 " for (var key in msg) {\n",
4541 " if (!(key in fig.buttons)) {\n",
4542 " continue;\n",
4543 " }\n",
4544 " fig.buttons[key].disabled = !msg[key];\n",
4545 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
4546 " }\n",
4547 "};\n",
4548 "\n",
4549 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
4550 " if (msg['mode'] === 'PAN') {\n",
4551 " fig.buttons['Pan'].classList.add('active');\n",
4552 " fig.buttons['Zoom'].classList.remove('active');\n",
4553 " } else if (msg['mode'] === 'ZOOM') {\n",
4554 " fig.buttons['Pan'].classList.remove('active');\n",
4555 " fig.buttons['Zoom'].classList.add('active');\n",
4556 " } else {\n",
4557 " fig.buttons['Pan'].classList.remove('active');\n",
4558 " fig.buttons['Zoom'].classList.remove('active');\n",
4559 " }\n",
4560 "};\n",
4561 "\n",
4562 "mpl.figure.prototype.updated_canvas_event = function () {\n",
4563 " // Called whenever the canvas gets updated.\n",
4564 " this.send_message('ack', {});\n",
4565 "};\n",
4566 "\n",
4567 "// A function to construct a web socket function for onmessage handling.\n",
4568 "// Called in the figure constructor.\n",
4569 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
4570 " return function socket_on_message(evt) {\n",
4571 " if (evt.data instanceof Blob) {\n",
4572 " /* FIXME: We get \"Resource interpreted as Image but\n",
4573 " * transferred with MIME type text/plain:\" errors on\n",
4574 " * Chrome. But how to set the MIME type? It doesn't seem\n",
4575 " * to be part of the websocket stream */\n",
4576 " evt.data.type = 'image/png';\n",
4577 "\n",
4578 " /* Free the memory for the previous frames */\n",
4579 " if (fig.imageObj.src) {\n",
4580 " (window.URL || window.webkitURL).revokeObjectURL(\n",
4581 " fig.imageObj.src\n",
4582 " );\n",
4583 " }\n",
4584 "\n",
4585 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
4586 " evt.data\n",
4587 " );\n",
4588 " fig.updated_canvas_event();\n",
4589 " fig.waiting = false;\n",
4590 " return;\n",
4591 " } else if (\n",
4592 " typeof evt.data === 'string' &&\n",
4593 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
4594 " ) {\n",
4595 " fig.imageObj.src = evt.data;\n",
4596 " fig.updated_canvas_event();\n",
4597 " fig.waiting = false;\n",
4598 " return;\n",
4599 " }\n",
4600 "\n",
4601 " var msg = JSON.parse(evt.data);\n",
4602 " var msg_type = msg['type'];\n",
4603 "\n",
4604 " // Call the \"handle_{type}\" callback, which takes\n",
4605 " // the figure and JSON message as its only arguments.\n",
4606 " try {\n",
4607 " var callback = fig['handle_' + msg_type];\n",
4608 " } catch (e) {\n",
4609 " console.log(\n",
4610 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
4611 " msg\n",
4612 " );\n",
4613 " return;\n",
4614 " }\n",
4615 "\n",
4616 " if (callback) {\n",
4617 " try {\n",
4618 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
4619 " callback(fig, msg);\n",
4620 " } catch (e) {\n",
4621 " console.log(\n",
4622 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
4623 " e,\n",
4624 " e.stack,\n",
4625 " msg\n",
4626 " );\n",
4627 " }\n",
4628 " }\n",
4629 " };\n",
4630 "};\n",
4631 "\n",
4632 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
4633 "mpl.findpos = function (e) {\n",
4634 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
4635 " var targ;\n",
4636 " if (!e) {\n",
4637 " e = window.event;\n",
4638 " }\n",
4639 " if (e.target) {\n",
4640 " targ = e.target;\n",
4641 " } else if (e.srcElement) {\n",
4642 " targ = e.srcElement;\n",
4643 " }\n",
4644 " if (targ.nodeType === 3) {\n",
4645 " // defeat Safari bug\n",
4646 " targ = targ.parentNode;\n",
4647 " }\n",
4648 "\n",
4649 " // pageX,Y are the mouse positions relative to the document\n",
4650 " var boundingRect = targ.getBoundingClientRect();\n",
4651 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
4652 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
4653 "\n",
4654 " return { x: x, y: y };\n",
4655 "};\n",
4656 "\n",
4657 "/*\n",
4658 " * return a copy of an object with only non-object keys\n",
4659 " * we need this to avoid circular references\n",
4660 " * http://stackoverflow.com/a/24161582/3208463\n",
4661 " */\n",
4662 "function simpleKeys(original) {\n",
4663 " return Object.keys(original).reduce(function (obj, key) {\n",
4664 " if (typeof original[key] !== 'object') {\n",
4665 " obj[key] = original[key];\n",
4666 " }\n",
4667 " return obj;\n",
4668 " }, {});\n",
4669 "}\n",
4670 "\n",
4671 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
4672 " var canvas_pos = mpl.findpos(event);\n",
4673 "\n",
4674 " if (name === 'button_press') {\n",
4675 " this.canvas.focus();\n",
4676 " this.canvas_div.focus();\n",
4677 " }\n",
4678 "\n",
4679 " var x = canvas_pos.x * this.ratio;\n",
4680 " var y = canvas_pos.y * this.ratio;\n",
4681 "\n",
4682 " this.send_message(name, {\n",
4683 " x: x,\n",
4684 " y: y,\n",
4685 " button: event.button,\n",
4686 " step: event.step,\n",
4687 " guiEvent: simpleKeys(event),\n",
4688 " });\n",
4689 "\n",
4690 " /* This prevents the web browser from automatically changing to\n",
4691 " * the text insertion cursor when the button is pressed. We want\n",
4692 " * to control all of the cursor setting manually through the\n",
4693 " * 'cursor' event from matplotlib */\n",
4694 " event.preventDefault();\n",
4695 " return false;\n",
4696 "};\n",
4697 "\n",
4698 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
4699 " // Handle any extra behaviour associated with a key event\n",
4700 "};\n",
4701 "\n",
4702 "mpl.figure.prototype.key_event = function (event, name) {\n",
4703 " // Prevent repeat events\n",
4704 " if (name === 'key_press') {\n",
4705 " if (event.which === this._key) {\n",
4706 " return;\n",
4707 " } else {\n",
4708 " this._key = event.which;\n",
4709 " }\n",
4710 " }\n",
4711 " if (name === 'key_release') {\n",
4712 " this._key = null;\n",
4713 " }\n",
4714 "\n",
4715 " var value = '';\n",
4716 " if (event.ctrlKey && event.which !== 17) {\n",
4717 " value += 'ctrl+';\n",
4718 " }\n",
4719 " if (event.altKey && event.which !== 18) {\n",
4720 " value += 'alt+';\n",
4721 " }\n",
4722 " if (event.shiftKey && event.which !== 16) {\n",
4723 " value += 'shift+';\n",
4724 " }\n",
4725 "\n",
4726 " value += 'k';\n",
4727 " value += event.which.toString();\n",
4728 "\n",
4729 " this._key_event_extra(event, name);\n",
4730 "\n",
4731 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
4732 " return false;\n",
4733 "};\n",
4734 "\n",
4735 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
4736 " if (name === 'download') {\n",
4737 " this.handle_save(this, null);\n",
4738 " } else {\n",
4739 " this.send_message('toolbar_button', { name: name });\n",
4740 " }\n",
4741 "};\n",
4742 "\n",
4743 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
4744 " this.message.textContent = tooltip;\n",
4745 "};\n",
4746 "\n",
4747 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
4748 "// prettier-ignore\n",
4749 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
4750 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
4751 "\n",
4752 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
4753 "\n",
4754 "mpl.default_extension = \"png\";/* global mpl */\n",
4755 "\n",
4756 "var comm_websocket_adapter = function (comm) {\n",
4757 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
4758 " // object with the appropriate methods. Currently this is a non binary\n",
4759 " // socket, so there is still some room for performance tuning.\n",
4760 " var ws = {};\n",
4761 "\n",
4762 " ws.close = function () {\n",
4763 " comm.close();\n",
4764 " };\n",
4765 " ws.send = function (m) {\n",
4766 " //console.log('sending', m);\n",
4767 " comm.send(m);\n",
4768 " };\n",
4769 " // Register the callback with on_msg.\n",
4770 " comm.on_msg(function (msg) {\n",
4771 " //console.log('receiving', msg['content']['data'], msg);\n",
4772 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
4773 " ws.onmessage(msg['content']['data']);\n",
4774 " });\n",
4775 " return ws;\n",
4776 "};\n",
4777 "\n",
4778 "mpl.mpl_figure_comm = function (comm, msg) {\n",
4779 " // This is the function which gets called when the mpl process\n",
4780 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
4781 "\n",
4782 " var id = msg.content.data.id;\n",
4783 " // Get hold of the div created by the display call when the Comm\n",
4784 " // socket was opened in Python.\n",
4785 " var element = document.getElementById(id);\n",
4786 " var ws_proxy = comm_websocket_adapter(comm);\n",
4787 "\n",
4788 " function ondownload(figure, _format) {\n",
4789 " window.open(figure.canvas.toDataURL());\n",
4790 " }\n",
4791 "\n",
4792 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
4793 "\n",
4794 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
4795 " // web socket which is closed, not our websocket->open comm proxy.\n",
4796 " ws_proxy.onopen();\n",
4797 "\n",
4798 " fig.parent_element = element;\n",
4799 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
4800 " if (!fig.cell_info) {\n",
4801 " console.error('Failed to find cell for figure', id, fig);\n",
4802 " return;\n",
4803 " }\n",
4804 " fig.cell_info[0].output_area.element.on(\n",
4805 " 'cleared',\n",
4806 " { fig: fig },\n",
4807 " fig._remove_fig_handler\n",
4808 " );\n",
4809 "};\n",
4810 "\n",
4811 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
4812 " var width = fig.canvas.width / fig.ratio;\n",
4813 " fig.cell_info[0].output_area.element.off(\n",
4814 " 'cleared',\n",
4815 " fig._remove_fig_handler\n",
4816 " );\n",
4817 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
4818 "\n",
4819 " // Update the output cell to use the data from the current canvas.\n",
4820 " fig.push_to_output();\n",
4821 " var dataURL = fig.canvas.toDataURL();\n",
4822 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
4823 " // the notebook keyboard shortcuts fail.\n",
4824 " IPython.keyboard_manager.enable();\n",
4825 " fig.parent_element.innerHTML =\n",
4826 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
4827 " fig.close_ws(fig, msg);\n",
4828 "};\n",
4829 "\n",
4830 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
4831 " fig.send_message('closing', msg);\n",
4832 " // fig.ws.close()\n",
4833 "};\n",
4834 "\n",
4835 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
4836 " // Turn the data on the canvas into data in the output cell.\n",
4837 " var width = this.canvas.width / this.ratio;\n",
4838 " var dataURL = this.canvas.toDataURL();\n",
4839 " this.cell_info[1]['text/html'] =\n",
4840 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
4841 "};\n",
4842 "\n",
4843 "mpl.figure.prototype.updated_canvas_event = function () {\n",
4844 " // Tell IPython that the notebook contents must change.\n",
4845 " IPython.notebook.set_dirty(true);\n",
4846 " this.send_message('ack', {});\n",
4847 " var fig = this;\n",
4848 " // Wait a second, then push the new image to the DOM so\n",
4849 " // that it is saved nicely (might be nice to debounce this).\n",
4850 " setTimeout(function () {\n",
4851 " fig.push_to_output();\n",
4852 " }, 1000);\n",
4853 "};\n",
4854 "\n",
4855 "mpl.figure.prototype._init_toolbar = function () {\n",
4856 " var fig = this;\n",
4857 "\n",
4858 " var toolbar = document.createElement('div');\n",
4859 " toolbar.classList = 'btn-toolbar';\n",
4860 " this.root.appendChild(toolbar);\n",
4861 "\n",
4862 " function on_click_closure(name) {\n",
4863 " return function (_event) {\n",
4864 " return fig.toolbar_button_onclick(name);\n",
4865 " };\n",
4866 " }\n",
4867 "\n",
4868 " function on_mouseover_closure(tooltip) {\n",
4869 " return function (event) {\n",
4870 " if (!event.currentTarget.disabled) {\n",
4871 " return fig.toolbar_button_onmouseover(tooltip);\n",
4872 " }\n",
4873 " };\n",
4874 " }\n",
4875 "\n",
4876 " fig.buttons = {};\n",
4877 " var buttonGroup = document.createElement('div');\n",
4878 " buttonGroup.classList = 'btn-group';\n",
4879 " var button;\n",
4880 " for (var toolbar_ind in mpl.toolbar_items) {\n",
4881 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
4882 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
4883 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
4884 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
4885 "\n",
4886 " if (!name) {\n",
4887 " /* Instead of a spacer, we start a new button group. */\n",
4888 " if (buttonGroup.hasChildNodes()) {\n",
4889 " toolbar.appendChild(buttonGroup);\n",
4890 " }\n",
4891 " buttonGroup = document.createElement('div');\n",
4892 " buttonGroup.classList = 'btn-group';\n",
4893 " continue;\n",
4894 " }\n",
4895 "\n",
4896 " button = fig.buttons[name] = document.createElement('button');\n",
4897 " button.classList = 'btn btn-default';\n",
4898 " button.href = '#';\n",
4899 " button.title = name;\n",
4900 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
4901 " button.addEventListener('click', on_click_closure(method_name));\n",
4902 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
4903 " buttonGroup.appendChild(button);\n",
4904 " }\n",
4905 "\n",
4906 " if (buttonGroup.hasChildNodes()) {\n",
4907 " toolbar.appendChild(buttonGroup);\n",
4908 " }\n",
4909 "\n",
4910 " // Add the status bar.\n",
4911 " var status_bar = document.createElement('span');\n",
4912 " status_bar.classList = 'mpl-message pull-right';\n",
4913 " toolbar.appendChild(status_bar);\n",
4914 " this.message = status_bar;\n",
4915 "\n",
4916 " // Add the close button to the window.\n",
4917 " var buttongrp = document.createElement('div');\n",
4918 " buttongrp.classList = 'btn-group inline pull-right';\n",
4919 " button = document.createElement('button');\n",
4920 " button.classList = 'btn btn-mini btn-primary';\n",
4921 " button.href = '#';\n",
4922 " button.title = 'Stop Interaction';\n",
4923 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
4924 " button.addEventListener('click', function (_evt) {\n",
4925 " fig.handle_close(fig, {});\n",
4926 " });\n",
4927 " button.addEventListener(\n",
4928 " 'mouseover',\n",
4929 " on_mouseover_closure('Stop Interaction')\n",
4930 " );\n",
4931 " buttongrp.appendChild(button);\n",
4932 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
4933 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
4934 "};\n",
4935 "\n",
4936 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
4937 " var fig = event.data.fig;\n",
4938 " if (event.target !== this) {\n",
4939 " // Ignore bubbled events from children.\n",
4940 " return;\n",
4941 " }\n",
4942 " fig.close_ws(fig, {});\n",
4943 "};\n",
4944 "\n",
4945 "mpl.figure.prototype._root_extra_style = function (el) {\n",
4946 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
4947 "};\n",
4948 "\n",
4949 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
4950 " // this is important to make the div 'focusable\n",
4951 " el.setAttribute('tabindex', 0);\n",
4952 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
4953 " // off when our div gets focus\n",
4954 "\n",
4955 " // location in version 3\n",
4956 " if (IPython.notebook.keyboard_manager) {\n",
4957 " IPython.notebook.keyboard_manager.register_events(el);\n",
4958 " } else {\n",
4959 " // location in version 2\n",
4960 " IPython.keyboard_manager.register_events(el);\n",
4961 " }\n",
4962 "};\n",
4963 "\n",
4964 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
4965 " var manager = IPython.notebook.keyboard_manager;\n",
4966 " if (!manager) {\n",
4967 " manager = IPython.keyboard_manager;\n",
4968 " }\n",
4969 "\n",
4970 " // Check for shift+enter\n",
4971 " if (event.shiftKey && event.which === 13) {\n",
4972 " this.canvas_div.blur();\n",
4973 " // select the cell after this one\n",
4974 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
4975 " IPython.notebook.select(index + 1);\n",
4976 " }\n",
4977 "};\n",
4978 "\n",
4979 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
4980 " fig.ondownload(fig, null);\n",
4981 "};\n",
4982 "\n",
4983 "mpl.find_output_cell = function (html_output) {\n",
4984 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
4985 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
4986 " // IPython event is triggered only after the cells have been serialised, which for\n",
4987 " // our purposes (turning an active figure into a static one), is too late.\n",
4988 " var cells = IPython.notebook.get_cells();\n",
4989 " var ncells = cells.length;\n",
4990 " for (var i = 0; i < ncells; i++) {\n",
4991 " var cell = cells[i];\n",
4992 " if (cell.cell_type === 'code') {\n",
4993 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
4994 " var data = cell.output_area.outputs[j];\n",
4995 " if (data.data) {\n",
4996 " // IPython >= 3 moved mimebundle to data attribute of output\n",
4997 " data = data.data;\n",
4998 " }\n",
4999 " if (data['text/html'] === html_output) {\n",
5000 " return [cell, data, j];\n",
5001 " }\n",
5002 " }\n",
5003 " }\n",
5004 " }\n",
5005 "};\n",
5006 "\n",
5007 "// Register the function which deals with the matplotlib target/channel.\n",
5008 "// The kernel may be null if the page has been refreshed.\n",
5009 "if (IPython.notebook.kernel !== null) {\n",
5010 " IPython.notebook.kernel.comm_manager.register_target(\n",
5011 " 'matplotlib',\n",
5012 " mpl.mpl_figure_comm\n",
5013 " );\n",
5014 "}\n"
5015 ],
5016 "text/plain": [
5017 "<IPython.core.display.Javascript object>"
5018 ]
5019 },
5020 "metadata": {},
5021 "output_type": "display_data"
5022 },
5023 {
5024 "data": {
5025 "text/html": [
5026 "<div id='09269aeb-686f-480c-b161-46a688c80c85'></div>"
5027 ],
5028 "text/plain": [
5029 "<IPython.core.display.HTML object>"
5030 ]
5031 },
5032 "metadata": {},
5033 "output_type": "display_data"
5034 },
5035 {
5036 "name": "stderr",
5037 "output_type": "stream",
5038 "text": [
5039 "C:\\Users\\PC\\Pytho\\Applied-Machine-Learning-in-Python-master\\Source\\readonly\\adspy_shared_utilities.py:242: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later.\n",
5040 " plt.pcolormesh(xx, yy, Z, cmap=cmap_light)\n"
5041 ]
5042 },
5043 {
5044 "data": {
5045 "application/javascript": [
5046 "/* Put everything inside the global mpl namespace */\n",
5047 "/* global mpl */\n",
5048 "window.mpl = {};\n",
5049 "\n",
5050 "mpl.get_websocket_type = function () {\n",
5051 " if (typeof WebSocket !== 'undefined') {\n",
5052 " return WebSocket;\n",
5053 " } else if (typeof MozWebSocket !== 'undefined') {\n",
5054 " return MozWebSocket;\n",
5055 " } else {\n",
5056 " alert(\n",
5057 " 'Your browser does not have WebSocket support. ' +\n",
5058 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
5059 " 'Firefox 4 and 5 are also supported but you ' +\n",
5060 " 'have to enable WebSockets in about:config.'\n",
5061 " );\n",
5062 " }\n",
5063 "};\n",
5064 "\n",
5065 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
5066 " this.id = figure_id;\n",
5067 "\n",
5068 " this.ws = websocket;\n",
5069 "\n",
5070 " this.supports_binary = this.ws.binaryType !== undefined;\n",
5071 "\n",
5072 " if (!this.supports_binary) {\n",
5073 " var warnings = document.getElementById('mpl-warnings');\n",
5074 " if (warnings) {\n",
5075 " warnings.style.display = 'block';\n",
5076 " warnings.textContent =\n",
5077 " 'This browser does not support binary websocket messages. ' +\n",
5078 " 'Performance may be slow.';\n",
5079 " }\n",
5080 " }\n",
5081 "\n",
5082 " this.imageObj = new Image();\n",
5083 "\n",
5084 " this.context = undefined;\n",
5085 " this.message = undefined;\n",
5086 " this.canvas = undefined;\n",
5087 " this.rubberband_canvas = undefined;\n",
5088 " this.rubberband_context = undefined;\n",
5089 " this.format_dropdown = undefined;\n",
5090 "\n",
5091 " this.image_mode = 'full';\n",
5092 "\n",
5093 " this.root = document.createElement('div');\n",
5094 " this.root.setAttribute('style', 'display: inline-block');\n",
5095 " this._root_extra_style(this.root);\n",
5096 "\n",
5097 " parent_element.appendChild(this.root);\n",
5098 "\n",
5099 " this._init_header(this);\n",
5100 " this._init_canvas(this);\n",
5101 " this._init_toolbar(this);\n",
5102 "\n",
5103 " var fig = this;\n",
5104 "\n",
5105 " this.waiting = false;\n",
5106 "\n",
5107 " this.ws.onopen = function () {\n",
5108 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
5109 " fig.send_message('send_image_mode', {});\n",
5110 " if (fig.ratio !== 1) {\n",
5111 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
5112 " }\n",
5113 " fig.send_message('refresh', {});\n",
5114 " };\n",
5115 "\n",
5116 " this.imageObj.onload = function () {\n",
5117 " if (fig.image_mode === 'full') {\n",
5118 " // Full images could contain transparency (where diff images\n",
5119 " // almost always do), so we need to clear the canvas so that\n",
5120 " // there is no ghosting.\n",
5121 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
5122 " }\n",
5123 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
5124 " };\n",
5125 "\n",
5126 " this.imageObj.onunload = function () {\n",
5127 " fig.ws.close();\n",
5128 " };\n",
5129 "\n",
5130 " this.ws.onmessage = this._make_on_message_function(this);\n",
5131 "\n",
5132 " this.ondownload = ondownload;\n",
5133 "};\n",
5134 "\n",
5135 "mpl.figure.prototype._init_header = function () {\n",
5136 " var titlebar = document.createElement('div');\n",
5137 " titlebar.classList =\n",
5138 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
5139 " var titletext = document.createElement('div');\n",
5140 " titletext.classList = 'ui-dialog-title';\n",
5141 " titletext.setAttribute(\n",
5142 " 'style',\n",
5143 " 'width: 100%; text-align: center; padding: 3px;'\n",
5144 " );\n",
5145 " titlebar.appendChild(titletext);\n",
5146 " this.root.appendChild(titlebar);\n",
5147 " this.header = titletext;\n",
5148 "};\n",
5149 "\n",
5150 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
5151 "\n",
5152 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
5153 "\n",
5154 "mpl.figure.prototype._init_canvas = function () {\n",
5155 " var fig = this;\n",
5156 "\n",
5157 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
5158 " canvas_div.setAttribute(\n",
5159 " 'style',\n",
5160 " 'border: 1px solid #ddd;' +\n",
5161 " 'box-sizing: content-box;' +\n",
5162 " 'clear: both;' +\n",
5163 " 'min-height: 1px;' +\n",
5164 " 'min-width: 1px;' +\n",
5165 " 'outline: 0;' +\n",
5166 " 'overflow: hidden;' +\n",
5167 " 'position: relative;' +\n",
5168 " 'resize: both;'\n",
5169 " );\n",
5170 "\n",
5171 " function on_keyboard_event_closure(name) {\n",
5172 " return function (event) {\n",
5173 " return fig.key_event(event, name);\n",
5174 " };\n",
5175 " }\n",
5176 "\n",
5177 " canvas_div.addEventListener(\n",
5178 " 'keydown',\n",
5179 " on_keyboard_event_closure('key_press')\n",
5180 " );\n",
5181 " canvas_div.addEventListener(\n",
5182 " 'keyup',\n",
5183 " on_keyboard_event_closure('key_release')\n",
5184 " );\n",
5185 "\n",
5186 " this._canvas_extra_style(canvas_div);\n",
5187 " this.root.appendChild(canvas_div);\n",
5188 "\n",
5189 " var canvas = (this.canvas = document.createElement('canvas'));\n",
5190 " canvas.classList.add('mpl-canvas');\n",
5191 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
5192 "\n",
5193 " this.context = canvas.getContext('2d');\n",
5194 "\n",
5195 " var backingStore =\n",
5196 " this.context.backingStorePixelRatio ||\n",
5197 " this.context.webkitBackingStorePixelRatio ||\n",
5198 " this.context.mozBackingStorePixelRatio ||\n",
5199 " this.context.msBackingStorePixelRatio ||\n",
5200 " this.context.oBackingStorePixelRatio ||\n",
5201 " this.context.backingStorePixelRatio ||\n",
5202 " 1;\n",
5203 "\n",
5204 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
5205 "\n",
5206 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
5207 " 'canvas'\n",
5208 " ));\n",
5209 " rubberband_canvas.setAttribute(\n",
5210 " 'style',\n",
5211 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
5212 " );\n",
5213 "\n",
5214 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
5215 " if (this.ResizeObserver === undefined) {\n",
5216 " if (window.ResizeObserver !== undefined) {\n",
5217 " this.ResizeObserver = window.ResizeObserver;\n",
5218 " } else {\n",
5219 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
5220 " this.ResizeObserver = obs.ResizeObserver;\n",
5221 " }\n",
5222 " }\n",
5223 "\n",
5224 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
5225 " var nentries = entries.length;\n",
5226 " for (var i = 0; i < nentries; i++) {\n",
5227 " var entry = entries[i];\n",
5228 " var width, height;\n",
5229 " if (entry.contentBoxSize) {\n",
5230 " if (entry.contentBoxSize instanceof Array) {\n",
5231 " // Chrome 84 implements new version of spec.\n",
5232 " width = entry.contentBoxSize[0].inlineSize;\n",
5233 " height = entry.contentBoxSize[0].blockSize;\n",
5234 " } else {\n",
5235 " // Firefox implements old version of spec.\n",
5236 " width = entry.contentBoxSize.inlineSize;\n",
5237 " height = entry.contentBoxSize.blockSize;\n",
5238 " }\n",
5239 " } else {\n",
5240 " // Chrome <84 implements even older version of spec.\n",
5241 " width = entry.contentRect.width;\n",
5242 " height = entry.contentRect.height;\n",
5243 " }\n",
5244 "\n",
5245 " // Keep the size of the canvas and rubber band canvas in sync with\n",
5246 " // the canvas container.\n",
5247 " if (entry.devicePixelContentBoxSize) {\n",
5248 " // Chrome 84 implements new version of spec.\n",
5249 " canvas.setAttribute(\n",
5250 " 'width',\n",
5251 " entry.devicePixelContentBoxSize[0].inlineSize\n",
5252 " );\n",
5253 " canvas.setAttribute(\n",
5254 " 'height',\n",
5255 " entry.devicePixelContentBoxSize[0].blockSize\n",
5256 " );\n",
5257 " } else {\n",
5258 " canvas.setAttribute('width', width * fig.ratio);\n",
5259 " canvas.setAttribute('height', height * fig.ratio);\n",
5260 " }\n",
5261 " canvas.setAttribute(\n",
5262 " 'style',\n",
5263 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
5264 " );\n",
5265 "\n",
5266 " rubberband_canvas.setAttribute('width', width);\n",
5267 " rubberband_canvas.setAttribute('height', height);\n",
5268 "\n",
5269 " // And update the size in Python. We ignore the initial 0/0 size\n",
5270 " // that occurs as the element is placed into the DOM, which should\n",
5271 " // otherwise not happen due to the minimum size styling.\n",
5272 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
5273 " fig.request_resize(width, height);\n",
5274 " }\n",
5275 " }\n",
5276 " });\n",
5277 " this.resizeObserverInstance.observe(canvas_div);\n",
5278 "\n",
5279 " function on_mouse_event_closure(name) {\n",
5280 " return function (event) {\n",
5281 " return fig.mouse_event(event, name);\n",
5282 " };\n",
5283 " }\n",
5284 "\n",
5285 " rubberband_canvas.addEventListener(\n",
5286 " 'mousedown',\n",
5287 " on_mouse_event_closure('button_press')\n",
5288 " );\n",
5289 " rubberband_canvas.addEventListener(\n",
5290 " 'mouseup',\n",
5291 " on_mouse_event_closure('button_release')\n",
5292 " );\n",
5293 " // Throttle sequential mouse events to 1 every 20ms.\n",
5294 " rubberband_canvas.addEventListener(\n",
5295 " 'mousemove',\n",
5296 " on_mouse_event_closure('motion_notify')\n",
5297 " );\n",
5298 "\n",
5299 " rubberband_canvas.addEventListener(\n",
5300 " 'mouseenter',\n",
5301 " on_mouse_event_closure('figure_enter')\n",
5302 " );\n",
5303 " rubberband_canvas.addEventListener(\n",
5304 " 'mouseleave',\n",
5305 " on_mouse_event_closure('figure_leave')\n",
5306 " );\n",
5307 "\n",
5308 " canvas_div.addEventListener('wheel', function (event) {\n",
5309 " if (event.deltaY < 0) {\n",
5310 " event.step = 1;\n",
5311 " } else {\n",
5312 " event.step = -1;\n",
5313 " }\n",
5314 " on_mouse_event_closure('scroll')(event);\n",
5315 " });\n",
5316 "\n",
5317 " canvas_div.appendChild(canvas);\n",
5318 " canvas_div.appendChild(rubberband_canvas);\n",
5319 "\n",
5320 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
5321 " this.rubberband_context.strokeStyle = '#000000';\n",
5322 "\n",
5323 " this._resize_canvas = function (width, height, forward) {\n",
5324 " if (forward) {\n",
5325 " canvas_div.style.width = width + 'px';\n",
5326 " canvas_div.style.height = height + 'px';\n",
5327 " }\n",
5328 " };\n",
5329 "\n",
5330 " // Disable right mouse context menu.\n",
5331 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
5332 " event.preventDefault();\n",
5333 " return false;\n",
5334 " });\n",
5335 "\n",
5336 " function set_focus() {\n",
5337 " canvas.focus();\n",
5338 " canvas_div.focus();\n",
5339 " }\n",
5340 "\n",
5341 " window.setTimeout(set_focus, 100);\n",
5342 "};\n",
5343 "\n",
5344 "mpl.figure.prototype._init_toolbar = function () {\n",
5345 " var fig = this;\n",
5346 "\n",
5347 " var toolbar = document.createElement('div');\n",
5348 " toolbar.classList = 'mpl-toolbar';\n",
5349 " this.root.appendChild(toolbar);\n",
5350 "\n",
5351 " function on_click_closure(name) {\n",
5352 " return function (_event) {\n",
5353 " return fig.toolbar_button_onclick(name);\n",
5354 " };\n",
5355 " }\n",
5356 "\n",
5357 " function on_mouseover_closure(tooltip) {\n",
5358 " return function (event) {\n",
5359 " if (!event.currentTarget.disabled) {\n",
5360 " return fig.toolbar_button_onmouseover(tooltip);\n",
5361 " }\n",
5362 " };\n",
5363 " }\n",
5364 "\n",
5365 " fig.buttons = {};\n",
5366 " var buttonGroup = document.createElement('div');\n",
5367 " buttonGroup.classList = 'mpl-button-group';\n",
5368 " for (var toolbar_ind in mpl.toolbar_items) {\n",
5369 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
5370 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
5371 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
5372 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
5373 "\n",
5374 " if (!name) {\n",
5375 " /* Instead of a spacer, we start a new button group. */\n",
5376 " if (buttonGroup.hasChildNodes()) {\n",
5377 " toolbar.appendChild(buttonGroup);\n",
5378 " }\n",
5379 " buttonGroup = document.createElement('div');\n",
5380 " buttonGroup.classList = 'mpl-button-group';\n",
5381 " continue;\n",
5382 " }\n",
5383 "\n",
5384 " var button = (fig.buttons[name] = document.createElement('button'));\n",
5385 " button.classList = 'mpl-widget';\n",
5386 " button.setAttribute('role', 'button');\n",
5387 " button.setAttribute('aria-disabled', 'false');\n",
5388 " button.addEventListener('click', on_click_closure(method_name));\n",
5389 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
5390 "\n",
5391 " var icon_img = document.createElement('img');\n",
5392 " icon_img.src = '_images/' + image + '.png';\n",
5393 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
5394 " icon_img.alt = tooltip;\n",
5395 " button.appendChild(icon_img);\n",
5396 "\n",
5397 " buttonGroup.appendChild(button);\n",
5398 " }\n",
5399 "\n",
5400 " if (buttonGroup.hasChildNodes()) {\n",
5401 " toolbar.appendChild(buttonGroup);\n",
5402 " }\n",
5403 "\n",
5404 " var fmt_picker = document.createElement('select');\n",
5405 " fmt_picker.classList = 'mpl-widget';\n",
5406 " toolbar.appendChild(fmt_picker);\n",
5407 " this.format_dropdown = fmt_picker;\n",
5408 "\n",
5409 " for (var ind in mpl.extensions) {\n",
5410 " var fmt = mpl.extensions[ind];\n",
5411 " var option = document.createElement('option');\n",
5412 " option.selected = fmt === mpl.default_extension;\n",
5413 " option.innerHTML = fmt;\n",
5414 " fmt_picker.appendChild(option);\n",
5415 " }\n",
5416 "\n",
5417 " var status_bar = document.createElement('span');\n",
5418 " status_bar.classList = 'mpl-message';\n",
5419 " toolbar.appendChild(status_bar);\n",
5420 " this.message = status_bar;\n",
5421 "};\n",
5422 "\n",
5423 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
5424 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
5425 " // which will in turn request a refresh of the image.\n",
5426 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
5427 "};\n",
5428 "\n",
5429 "mpl.figure.prototype.send_message = function (type, properties) {\n",
5430 " properties['type'] = type;\n",
5431 " properties['figure_id'] = this.id;\n",
5432 " this.ws.send(JSON.stringify(properties));\n",
5433 "};\n",
5434 "\n",
5435 "mpl.figure.prototype.send_draw_message = function () {\n",
5436 " if (!this.waiting) {\n",
5437 " this.waiting = true;\n",
5438 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
5439 " }\n",
5440 "};\n",
5441 "\n",
5442 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
5443 " var format_dropdown = fig.format_dropdown;\n",
5444 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
5445 " fig.ondownload(fig, format);\n",
5446 "};\n",
5447 "\n",
5448 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
5449 " var size = msg['size'];\n",
5450 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
5451 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
5452 " fig.send_message('refresh', {});\n",
5453 " }\n",
5454 "};\n",
5455 "\n",
5456 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
5457 " var x0 = msg['x0'] / fig.ratio;\n",
5458 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
5459 " var x1 = msg['x1'] / fig.ratio;\n",
5460 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
5461 " x0 = Math.floor(x0) + 0.5;\n",
5462 " y0 = Math.floor(y0) + 0.5;\n",
5463 " x1 = Math.floor(x1) + 0.5;\n",
5464 " y1 = Math.floor(y1) + 0.5;\n",
5465 " var min_x = Math.min(x0, x1);\n",
5466 " var min_y = Math.min(y0, y1);\n",
5467 " var width = Math.abs(x1 - x0);\n",
5468 " var height = Math.abs(y1 - y0);\n",
5469 "\n",
5470 " fig.rubberband_context.clearRect(\n",
5471 " 0,\n",
5472 " 0,\n",
5473 " fig.canvas.width / fig.ratio,\n",
5474 " fig.canvas.height / fig.ratio\n",
5475 " );\n",
5476 "\n",
5477 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
5478 "};\n",
5479 "\n",
5480 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
5481 " // Updates the figure title.\n",
5482 " fig.header.textContent = msg['label'];\n",
5483 "};\n",
5484 "\n",
5485 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
5486 " var cursor = msg['cursor'];\n",
5487 " switch (cursor) {\n",
5488 " case 0:\n",
5489 " cursor = 'pointer';\n",
5490 " break;\n",
5491 " case 1:\n",
5492 " cursor = 'default';\n",
5493 " break;\n",
5494 " case 2:\n",
5495 " cursor = 'crosshair';\n",
5496 " break;\n",
5497 " case 3:\n",
5498 " cursor = 'move';\n",
5499 " break;\n",
5500 " }\n",
5501 " fig.rubberband_canvas.style.cursor = cursor;\n",
5502 "};\n",
5503 "\n",
5504 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
5505 " fig.message.textContent = msg['message'];\n",
5506 "};\n",
5507 "\n",
5508 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
5509 " // Request the server to send over a new figure.\n",
5510 " fig.send_draw_message();\n",
5511 "};\n",
5512 "\n",
5513 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
5514 " fig.image_mode = msg['mode'];\n",
5515 "};\n",
5516 "\n",
5517 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
5518 " for (var key in msg) {\n",
5519 " if (!(key in fig.buttons)) {\n",
5520 " continue;\n",
5521 " }\n",
5522 " fig.buttons[key].disabled = !msg[key];\n",
5523 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
5524 " }\n",
5525 "};\n",
5526 "\n",
5527 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
5528 " if (msg['mode'] === 'PAN') {\n",
5529 " fig.buttons['Pan'].classList.add('active');\n",
5530 " fig.buttons['Zoom'].classList.remove('active');\n",
5531 " } else if (msg['mode'] === 'ZOOM') {\n",
5532 " fig.buttons['Pan'].classList.remove('active');\n",
5533 " fig.buttons['Zoom'].classList.add('active');\n",
5534 " } else {\n",
5535 " fig.buttons['Pan'].classList.remove('active');\n",
5536 " fig.buttons['Zoom'].classList.remove('active');\n",
5537 " }\n",
5538 "};\n",
5539 "\n",
5540 "mpl.figure.prototype.updated_canvas_event = function () {\n",
5541 " // Called whenever the canvas gets updated.\n",
5542 " this.send_message('ack', {});\n",
5543 "};\n",
5544 "\n",
5545 "// A function to construct a web socket function for onmessage handling.\n",
5546 "// Called in the figure constructor.\n",
5547 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
5548 " return function socket_on_message(evt) {\n",
5549 " if (evt.data instanceof Blob) {\n",
5550 " /* FIXME: We get \"Resource interpreted as Image but\n",
5551 " * transferred with MIME type text/plain:\" errors on\n",
5552 " * Chrome. But how to set the MIME type? It doesn't seem\n",
5553 " * to be part of the websocket stream */\n",
5554 " evt.data.type = 'image/png';\n",
5555 "\n",
5556 " /* Free the memory for the previous frames */\n",
5557 " if (fig.imageObj.src) {\n",
5558 " (window.URL || window.webkitURL).revokeObjectURL(\n",
5559 " fig.imageObj.src\n",
5560 " );\n",
5561 " }\n",
5562 "\n",
5563 " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
5564 " evt.data\n",
5565 " );\n",
5566 " fig.updated_canvas_event();\n",
5567 " fig.waiting = false;\n",
5568 " return;\n",
5569 " } else if (\n",
5570 " typeof evt.data === 'string' &&\n",
5571 " evt.data.slice(0, 21) === 'data:image/png;base64'\n",
5572 " ) {\n",
5573 " fig.imageObj.src = evt.data;\n",
5574 " fig.updated_canvas_event();\n",
5575 " fig.waiting = false;\n",
5576 " return;\n",
5577 " }\n",
5578 "\n",
5579 " var msg = JSON.parse(evt.data);\n",
5580 " var msg_type = msg['type'];\n",
5581 "\n",
5582 " // Call the \"handle_{type}\" callback, which takes\n",
5583 " // the figure and JSON message as its only arguments.\n",
5584 " try {\n",
5585 " var callback = fig['handle_' + msg_type];\n",
5586 " } catch (e) {\n",
5587 " console.log(\n",
5588 " \"No handler for the '\" + msg_type + \"' message type: \",\n",
5589 " msg\n",
5590 " );\n",
5591 " return;\n",
5592 " }\n",
5593 "\n",
5594 " if (callback) {\n",
5595 " try {\n",
5596 " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
5597 " callback(fig, msg);\n",
5598 " } catch (e) {\n",
5599 " console.log(\n",
5600 " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
5601 " e,\n",
5602 " e.stack,\n",
5603 " msg\n",
5604 " );\n",
5605 " }\n",
5606 " }\n",
5607 " };\n",
5608 "};\n",
5609 "\n",
5610 "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
5611 "mpl.findpos = function (e) {\n",
5612 " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
5613 " var targ;\n",
5614 " if (!e) {\n",
5615 " e = window.event;\n",
5616 " }\n",
5617 " if (e.target) {\n",
5618 " targ = e.target;\n",
5619 " } else if (e.srcElement) {\n",
5620 " targ = e.srcElement;\n",
5621 " }\n",
5622 " if (targ.nodeType === 3) {\n",
5623 " // defeat Safari bug\n",
5624 " targ = targ.parentNode;\n",
5625 " }\n",
5626 "\n",
5627 " // pageX,Y are the mouse positions relative to the document\n",
5628 " var boundingRect = targ.getBoundingClientRect();\n",
5629 " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
5630 " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
5631 "\n",
5632 " return { x: x, y: y };\n",
5633 "};\n",
5634 "\n",
5635 "/*\n",
5636 " * return a copy of an object with only non-object keys\n",
5637 " * we need this to avoid circular references\n",
5638 " * http://stackoverflow.com/a/24161582/3208463\n",
5639 " */\n",
5640 "function simpleKeys(original) {\n",
5641 " return Object.keys(original).reduce(function (obj, key) {\n",
5642 " if (typeof original[key] !== 'object') {\n",
5643 " obj[key] = original[key];\n",
5644 " }\n",
5645 " return obj;\n",
5646 " }, {});\n",
5647 "}\n",
5648 "\n",
5649 "mpl.figure.prototype.mouse_event = function (event, name) {\n",
5650 " var canvas_pos = mpl.findpos(event);\n",
5651 "\n",
5652 " if (name === 'button_press') {\n",
5653 " this.canvas.focus();\n",
5654 " this.canvas_div.focus();\n",
5655 " }\n",
5656 "\n",
5657 " var x = canvas_pos.x * this.ratio;\n",
5658 " var y = canvas_pos.y * this.ratio;\n",
5659 "\n",
5660 " this.send_message(name, {\n",
5661 " x: x,\n",
5662 " y: y,\n",
5663 " button: event.button,\n",
5664 " step: event.step,\n",
5665 " guiEvent: simpleKeys(event),\n",
5666 " });\n",
5667 "\n",
5668 " /* This prevents the web browser from automatically changing to\n",
5669 " * the text insertion cursor when the button is pressed. We want\n",
5670 " * to control all of the cursor setting manually through the\n",
5671 " * 'cursor' event from matplotlib */\n",
5672 " event.preventDefault();\n",
5673 " return false;\n",
5674 "};\n",
5675 "\n",
5676 "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
5677 " // Handle any extra behaviour associated with a key event\n",
5678 "};\n",
5679 "\n",
5680 "mpl.figure.prototype.key_event = function (event, name) {\n",
5681 " // Prevent repeat events\n",
5682 " if (name === 'key_press') {\n",
5683 " if (event.which === this._key) {\n",
5684 " return;\n",
5685 " } else {\n",
5686 " this._key = event.which;\n",
5687 " }\n",
5688 " }\n",
5689 " if (name === 'key_release') {\n",
5690 " this._key = null;\n",
5691 " }\n",
5692 "\n",
5693 " var value = '';\n",
5694 " if (event.ctrlKey && event.which !== 17) {\n",
5695 " value += 'ctrl+';\n",
5696 " }\n",
5697 " if (event.altKey && event.which !== 18) {\n",
5698 " value += 'alt+';\n",
5699 " }\n",
5700 " if (event.shiftKey && event.which !== 16) {\n",
5701 " value += 'shift+';\n",
5702 " }\n",
5703 "\n",
5704 " value += 'k';\n",
5705 " value += event.which.toString();\n",
5706 "\n",
5707 " this._key_event_extra(event, name);\n",
5708 "\n",
5709 " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
5710 " return false;\n",
5711 "};\n",
5712 "\n",
5713 "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
5714 " if (name === 'download') {\n",
5715 " this.handle_save(this, null);\n",
5716 " } else {\n",
5717 " this.send_message('toolbar_button', { name: name });\n",
5718 " }\n",
5719 "};\n",
5720 "\n",
5721 "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
5722 " this.message.textContent = tooltip;\n",
5723 "};\n",
5724 "\n",
5725 "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n",
5726 "// prettier-ignore\n",
5727 "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n",
5728 "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\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
5729 "\n",
5730 "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
5731 "\n",
5732 "mpl.default_extension = \"png\";/* global mpl */\n",
5733 "\n",
5734 "var comm_websocket_adapter = function (comm) {\n",
5735 " // Create a \"websocket\"-like object which calls the given IPython comm\n",
5736 " // object with the appropriate methods. Currently this is a non binary\n",
5737 " // socket, so there is still some room for performance tuning.\n",
5738 " var ws = {};\n",
5739 "\n",
5740 " ws.close = function () {\n",
5741 " comm.close();\n",
5742 " };\n",
5743 " ws.send = function (m) {\n",
5744 " //console.log('sending', m);\n",
5745 " comm.send(m);\n",
5746 " };\n",
5747 " // Register the callback with on_msg.\n",
5748 " comm.on_msg(function (msg) {\n",
5749 " //console.log('receiving', msg['content']['data'], msg);\n",
5750 " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
5751 " ws.onmessage(msg['content']['data']);\n",
5752 " });\n",
5753 " return ws;\n",
5754 "};\n",
5755 "\n",
5756 "mpl.mpl_figure_comm = function (comm, msg) {\n",
5757 " // This is the function which gets called when the mpl process\n",
5758 " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
5759 "\n",
5760 " var id = msg.content.data.id;\n",
5761 " // Get hold of the div created by the display call when the Comm\n",
5762 " // socket was opened in Python.\n",
5763 " var element = document.getElementById(id);\n",
5764 " var ws_proxy = comm_websocket_adapter(comm);\n",
5765 "\n",
5766 " function ondownload(figure, _format) {\n",
5767 " window.open(figure.canvas.toDataURL());\n",
5768 " }\n",
5769 "\n",
5770 " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
5771 "\n",
5772 " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
5773 " // web socket which is closed, not our websocket->open comm proxy.\n",
5774 " ws_proxy.onopen();\n",
5775 "\n",
5776 " fig.parent_element = element;\n",
5777 " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
5778 " if (!fig.cell_info) {\n",
5779 " console.error('Failed to find cell for figure', id, fig);\n",
5780 " return;\n",
5781 " }\n",
5782 " fig.cell_info[0].output_area.element.on(\n",
5783 " 'cleared',\n",
5784 " { fig: fig },\n",
5785 " fig._remove_fig_handler\n",
5786 " );\n",
5787 "};\n",
5788 "\n",
5789 "mpl.figure.prototype.handle_close = function (fig, msg) {\n",
5790 " var width = fig.canvas.width / fig.ratio;\n",
5791 " fig.cell_info[0].output_area.element.off(\n",
5792 " 'cleared',\n",
5793 " fig._remove_fig_handler\n",
5794 " );\n",
5795 " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n",
5796 "\n",
5797 " // Update the output cell to use the data from the current canvas.\n",
5798 " fig.push_to_output();\n",
5799 " var dataURL = fig.canvas.toDataURL();\n",
5800 " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
5801 " // the notebook keyboard shortcuts fail.\n",
5802 " IPython.keyboard_manager.enable();\n",
5803 " fig.parent_element.innerHTML =\n",
5804 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
5805 " fig.close_ws(fig, msg);\n",
5806 "};\n",
5807 "\n",
5808 "mpl.figure.prototype.close_ws = function (fig, msg) {\n",
5809 " fig.send_message('closing', msg);\n",
5810 " // fig.ws.close()\n",
5811 "};\n",
5812 "\n",
5813 "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
5814 " // Turn the data on the canvas into data in the output cell.\n",
5815 " var width = this.canvas.width / this.ratio;\n",
5816 " var dataURL = this.canvas.toDataURL();\n",
5817 " this.cell_info[1]['text/html'] =\n",
5818 " '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
5819 "};\n",
5820 "\n",
5821 "mpl.figure.prototype.updated_canvas_event = function () {\n",
5822 " // Tell IPython that the notebook contents must change.\n",
5823 " IPython.notebook.set_dirty(true);\n",
5824 " this.send_message('ack', {});\n",
5825 " var fig = this;\n",
5826 " // Wait a second, then push the new image to the DOM so\n",
5827 " // that it is saved nicely (might be nice to debounce this).\n",
5828 " setTimeout(function () {\n",
5829 " fig.push_to_output();\n",
5830 " }, 1000);\n",
5831 "};\n",
5832 "\n",
5833 "mpl.figure.prototype._init_toolbar = function () {\n",
5834 " var fig = this;\n",
5835 "\n",
5836 " var toolbar = document.createElement('div');\n",
5837 " toolbar.classList = 'btn-toolbar';\n",
5838 " this.root.appendChild(toolbar);\n",
5839 "\n",
5840 " function on_click_closure(name) {\n",
5841 " return function (_event) {\n",
5842 " return fig.toolbar_button_onclick(name);\n",
5843 " };\n",
5844 " }\n",
5845 "\n",
5846 " function on_mouseover_closure(tooltip) {\n",
5847 " return function (event) {\n",
5848 " if (!event.currentTarget.disabled) {\n",
5849 " return fig.toolbar_button_onmouseover(tooltip);\n",
5850 " }\n",
5851 " };\n",
5852 " }\n",
5853 "\n",
5854 " fig.buttons = {};\n",
5855 " var buttonGroup = document.createElement('div');\n",
5856 " buttonGroup.classList = 'btn-group';\n",
5857 " var button;\n",
5858 " for (var toolbar_ind in mpl.toolbar_items) {\n",
5859 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
5860 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
5861 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
5862 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
5863 "\n",
5864 " if (!name) {\n",
5865 " /* Instead of a spacer, we start a new button group. */\n",
5866 " if (buttonGroup.hasChildNodes()) {\n",
5867 " toolbar.appendChild(buttonGroup);\n",
5868 " }\n",
5869 " buttonGroup = document.createElement('div');\n",
5870 " buttonGroup.classList = 'btn-group';\n",
5871 " continue;\n",
5872 " }\n",
5873 "\n",
5874 " button = fig.buttons[name] = document.createElement('button');\n",
5875 " button.classList = 'btn btn-default';\n",
5876 " button.href = '#';\n",
5877 " button.title = name;\n",
5878 " button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
5879 " button.addEventListener('click', on_click_closure(method_name));\n",
5880 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
5881 " buttonGroup.appendChild(button);\n",
5882 " }\n",
5883 "\n",
5884 " if (buttonGroup.hasChildNodes()) {\n",
5885 " toolbar.appendChild(buttonGroup);\n",
5886 " }\n",
5887 "\n",
5888 " // Add the status bar.\n",
5889 " var status_bar = document.createElement('span');\n",
5890 " status_bar.classList = 'mpl-message pull-right';\n",
5891 " toolbar.appendChild(status_bar);\n",
5892 " this.message = status_bar;\n",
5893 "\n",
5894 " // Add the close button to the window.\n",
5895 " var buttongrp = document.createElement('div');\n",
5896 " buttongrp.classList = 'btn-group inline pull-right';\n",
5897 " button = document.createElement('button');\n",
5898 " button.classList = 'btn btn-mini btn-primary';\n",
5899 " button.href = '#';\n",
5900 " button.title = 'Stop Interaction';\n",
5901 " button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
5902 " button.addEventListener('click', function (_evt) {\n",
5903 " fig.handle_close(fig, {});\n",
5904 " });\n",
5905 " button.addEventListener(\n",
5906 " 'mouseover',\n",
5907 " on_mouseover_closure('Stop Interaction')\n",
5908 " );\n",
5909 " buttongrp.appendChild(button);\n",
5910 " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
5911 " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
5912 "};\n",
5913 "\n",
5914 "mpl.figure.prototype._remove_fig_handler = function (event) {\n",
5915 " var fig = event.data.fig;\n",
5916 " if (event.target !== this) {\n",
5917 " // Ignore bubbled events from children.\n",
5918 " return;\n",
5919 " }\n",
5920 " fig.close_ws(fig, {});\n",
5921 "};\n",
5922 "\n",
5923 "mpl.figure.prototype._root_extra_style = function (el) {\n",
5924 " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
5925 "};\n",
5926 "\n",
5927 "mpl.figure.prototype._canvas_extra_style = function (el) {\n",
5928 " // this is important to make the div 'focusable\n",
5929 " el.setAttribute('tabindex', 0);\n",
5930 " // reach out to IPython and tell the keyboard manager to turn it's self\n",
5931 " // off when our div gets focus\n",
5932 "\n",
5933 " // location in version 3\n",
5934 " if (IPython.notebook.keyboard_manager) {\n",
5935 " IPython.notebook.keyboard_manager.register_events(el);\n",
5936 " } else {\n",
5937 " // location in version 2\n",
5938 " IPython.keyboard_manager.register_events(el);\n",
5939 " }\n",
5940 "};\n",
5941 "\n",
5942 "mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
5943 " var manager = IPython.notebook.keyboard_manager;\n",
5944 " if (!manager) {\n",
5945 " manager = IPython.keyboard_manager;\n",
5946 " }\n",
5947 "\n",
5948 " // Check for shift+enter\n",
5949 " if (event.shiftKey && event.which === 13) {\n",
5950 " this.canvas_div.blur();\n",
5951 " // select the cell after this one\n",
5952 " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
5953 " IPython.notebook.select(index + 1);\n",
5954 " }\n",
5955 "};\n",
5956 "\n",
5957 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
5958 " fig.ondownload(fig, null);\n",
5959 "};\n",
5960 "\n",
5961 "mpl.find_output_cell = function (html_output) {\n",
5962 " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
5963 " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
5964 " // IPython event is triggered only after the cells have been serialised, which for\n",
5965 " // our purposes (turning an active figure into a static one), is too late.\n",
5966 " var cells = IPython.notebook.get_cells();\n",
5967 " var ncells = cells.length;\n",
5968 " for (var i = 0; i < ncells; i++) {\n",
5969 " var cell = cells[i];\n",
5970 " if (cell.cell_type === 'code') {\n",
5971 " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
5972 " var data = cell.output_area.outputs[j];\n",
5973 " if (data.data) {\n",
5974 " // IPython >= 3 moved mimebundle to data attribute of output\n",
5975 " data = data.data;\n",
5976 " }\n",
5977 " if (data['text/html'] === html_output) {\n",
5978 " return [cell, data, j];\n",
5979 " }\n",
5980 " }\n",
5981 " }\n",
5982 " }\n",
5983 "};\n",
5984 "\n",
5985 "// Register the function which deals with the matplotlib target/channel.\n",
5986 "// The kernel may be null if the page has been refreshed.\n",
5987 "if (IPython.notebook.kernel !== null) {\n",
5988 " IPython.notebook.kernel.comm_manager.register_target(\n",
5989 " 'matplotlib',\n",
5990 " mpl.mpl_figure_comm\n",
5991 " );\n",
5992 "}\n"
5993 ],
5994 "text/plain": [
5995 "<IPython.core.display.Javascript object>"
5996 ]
5997 },
5998 "metadata": {},
5999 "output_type": "display_data"
6000 },
6001 {
6002 "data": {
6003 "text/html": [
6004 "<div id='e9903399-4037-40b0-9050-e42627f7ad74'></div>"
6005 ],
6006 "text/plain": [
6007 "<IPython.core.display.HTML object>"
6008 ]
6009 },
6010 "metadata": {},
6011 "output_type": "display_data"
6012 },
6013 {
6014 "name": "stderr",
6015 "output_type": "stream",
6016 "text": [
6017 "C:\\Users\\PC\\Pytho\\Applied-Machine-Learning-in-Python-master\\Source\\readonly\\adspy_shared_utilities.py:242: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading']. This will become an error two minor releases later.\n",
6018 " plt.pcolormesh(xx, yy, Z, cmap=cmap_light)\n"
6019 ]
6020 },
6021 {
6022 "data": {
6023 "application/javascript": [
6024 "/* Put everything inside the global mpl namespace */\n",
6025 "/* global mpl */\n",
6026 "window.mpl = {};\n",
6027 "\n",
6028 "mpl.get_websocket_type = function () {\n",
6029 " if (typeof WebSocket !== 'undefined') {\n",
6030 " return WebSocket;\n",
6031 " } else if (typeof MozWebSocket !== 'undefined') {\n",
6032 " return MozWebSocket;\n",
6033 " } else {\n",
6034 " alert(\n",
6035 " 'Your browser does not have WebSocket support. ' +\n",
6036 " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
6037 " 'Firefox 4 and 5 are also supported but you ' +\n",
6038 " 'have to enable WebSockets in about:config.'\n",
6039 " );\n",
6040 " }\n",
6041 "};\n",
6042 "\n",
6043 "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
6044 " this.id = figure_id;\n",
6045 "\n",
6046 " this.ws = websocket;\n",
6047 "\n",
6048 " this.supports_binary = this.ws.binaryType !== undefined;\n",
6049 "\n",
6050 " if (!this.supports_binary) {\n",
6051 " var warnings = document.getElementById('mpl-warnings');\n",
6052 " if (warnings) {\n",
6053 " warnings.style.display = 'block';\n",
6054 " warnings.textContent =\n",
6055 " 'This browser does not support binary websocket messages. ' +\n",
6056 " 'Performance may be slow.';\n",
6057 " }\n",
6058 " }\n",
6059 "\n",
6060 " this.imageObj = new Image();\n",
6061 "\n",
6062 " this.context = undefined;\n",
6063 " this.message = undefined;\n",
6064 " this.canvas = undefined;\n",
6065 " this.rubberband_canvas = undefined;\n",
6066 " this.rubberband_context = undefined;\n",
6067 " this.format_dropdown = undefined;\n",
6068 "\n",
6069 " this.image_mode = 'full';\n",
6070 "\n",
6071 " this.root = document.createElement('div');\n",
6072 " this.root.setAttribute('style', 'display: inline-block');\n",
6073 " this._root_extra_style(this.root);\n",
6074 "\n",
6075 " parent_element.appendChild(this.root);\n",
6076 "\n",
6077 " this._init_header(this);\n",
6078 " this._init_canvas(this);\n",
6079 " this._init_toolbar(this);\n",
6080 "\n",
6081 " var fig = this;\n",
6082 "\n",
6083 " this.waiting = false;\n",
6084 "\n",
6085 " this.ws.onopen = function () {\n",
6086 " fig.send_message('supports_binary', { value: fig.supports_binary });\n",
6087 " fig.send_message('send_image_mode', {});\n",
6088 " if (fig.ratio !== 1) {\n",
6089 " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
6090 " }\n",
6091 " fig.send_message('refresh', {});\n",
6092 " };\n",
6093 "\n",
6094 " this.imageObj.onload = function () {\n",
6095 " if (fig.image_mode === 'full') {\n",
6096 " // Full images could contain transparency (where diff images\n",
6097 " // almost always do), so we need to clear the canvas so that\n",
6098 " // there is no ghosting.\n",
6099 " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
6100 " }\n",
6101 " fig.context.drawImage(fig.imageObj, 0, 0);\n",
6102 " };\n",
6103 "\n",
6104 " this.imageObj.onunload = function () {\n",
6105 " fig.ws.close();\n",
6106 " };\n",
6107 "\n",
6108 " this.ws.onmessage = this._make_on_message_function(this);\n",
6109 "\n",
6110 " this.ondownload = ondownload;\n",
6111 "};\n",
6112 "\n",
6113 "mpl.figure.prototype._init_header = function () {\n",
6114 " var titlebar = document.createElement('div');\n",
6115 " titlebar.classList =\n",
6116 " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
6117 " var titletext = document.createElement('div');\n",
6118 " titletext.classList = 'ui-dialog-title';\n",
6119 " titletext.setAttribute(\n",
6120 " 'style',\n",
6121 " 'width: 100%; text-align: center; padding: 3px;'\n",
6122 " );\n",
6123 " titlebar.appendChild(titletext);\n",
6124 " this.root.appendChild(titlebar);\n",
6125 " this.header = titletext;\n",
6126 "};\n",
6127 "\n",
6128 "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
6129 "\n",
6130 "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
6131 "\n",
6132 "mpl.figure.prototype._init_canvas = function () {\n",
6133 " var fig = this;\n",
6134 "\n",
6135 " var canvas_div = (this.canvas_div = document.createElement('div'));\n",
6136 " canvas_div.setAttribute(\n",
6137 " 'style',\n",
6138 " 'border: 1px solid #ddd;' +\n",
6139 " 'box-sizing: content-box;' +\n",
6140 " 'clear: both;' +\n",
6141 " 'min-height: 1px;' +\n",
6142 " 'min-width: 1px;' +\n",
6143 " 'outline: 0;' +\n",
6144 " 'overflow: hidden;' +\n",
6145 " 'position: relative;' +\n",
6146 " 'resize: both;'\n",
6147 " );\n",
6148 "\n",
6149 " function on_keyboard_event_closure(name) {\n",
6150 " return function (event) {\n",
6151 " return fig.key_event(event, name);\n",
6152 " };\n",
6153 " }\n",
6154 "\n",
6155 " canvas_div.addEventListener(\n",
6156 " 'keydown',\n",
6157 " on_keyboard_event_closure('key_press')\n",
6158 " );\n",
6159 " canvas_div.addEventListener(\n",
6160 " 'keyup',\n",
6161 " on_keyboard_event_closure('key_release')\n",
6162 " );\n",
6163 "\n",
6164 " this._canvas_extra_style(canvas_div);\n",
6165 " this.root.appendChild(canvas_div);\n",
6166 "\n",
6167 " var canvas = (this.canvas = document.createElement('canvas'));\n",
6168 " canvas.classList.add('mpl-canvas');\n",
6169 " canvas.setAttribute('style', 'box-sizing: content-box;');\n",
6170 "\n",
6171 " this.context = canvas.getContext('2d');\n",
6172 "\n",
6173 " var backingStore =\n",
6174 " this.context.backingStorePixelRatio ||\n",
6175 " this.context.webkitBackingStorePixelRatio ||\n",
6176 " this.context.mozBackingStorePixelRatio ||\n",
6177 " this.context.msBackingStorePixelRatio ||\n",
6178 " this.context.oBackingStorePixelRatio ||\n",
6179 " this.context.backingStorePixelRatio ||\n",
6180 " 1;\n",
6181 "\n",
6182 " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
6183 "\n",
6184 " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
6185 " 'canvas'\n",
6186 " ));\n",
6187 " rubberband_canvas.setAttribute(\n",
6188 " 'style',\n",
6189 " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
6190 " );\n",
6191 "\n",
6192 " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n",
6193 " if (this.ResizeObserver === undefined) {\n",
6194 " if (window.ResizeObserver !== undefined) {\n",
6195 " this.ResizeObserver = window.ResizeObserver;\n",
6196 " } else {\n",
6197 " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n",
6198 " this.ResizeObserver = obs.ResizeObserver;\n",
6199 " }\n",
6200 " }\n",
6201 "\n",
6202 " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n",
6203 " var nentries = entries.length;\n",
6204 " for (var i = 0; i < nentries; i++) {\n",
6205 " var entry = entries[i];\n",
6206 " var width, height;\n",
6207 " if (entry.contentBoxSize) {\n",
6208 " if (entry.contentBoxSize instanceof Array) {\n",
6209 " // Chrome 84 implements new version of spec.\n",
6210 " width = entry.contentBoxSize[0].inlineSize;\n",
6211 " height = entry.contentBoxSize[0].blockSize;\n",
6212 " } else {\n",
6213 " // Firefox implements old version of spec.\n",
6214 " width = entry.contentBoxSize.inlineSize;\n",
6215 " height = entry.contentBoxSize.blockSize;\n",
6216 " }\n",
6217 " } else {\n",
6218 " // Chrome <84 implements even older version of spec.\n",
6219 " width = entry.contentRect.width;\n",
6220 " height = entry.contentRect.height;\n",
6221 " }\n",
6222 "\n",
6223 " // Keep the size of the canvas and rubber band canvas in sync with\n",
6224 " // the canvas container.\n",
6225 " if (entry.devicePixelContentBoxSize) {\n",
6226 " // Chrome 84 implements new version of spec.\n",
6227 " canvas.setAttribute(\n",
6228 " 'width',\n",
6229 " entry.devicePixelContentBoxSize[0].inlineSize\n",
6230 " );\n",
6231 " canvas.setAttribute(\n",
6232 " 'height',\n",
6233 " entry.devicePixelContentBoxSize[0].blockSize\n",
6234 " );\n",
6235 " } else {\n",
6236 " canvas.setAttribute('width', width * fig.ratio);\n",
6237 " canvas.setAttribute('height', height * fig.ratio);\n",
6238 " }\n",
6239 " canvas.setAttribute(\n",
6240 " 'style',\n",
6241 " 'width: ' + width + 'px; height: ' + height + 'px;'\n",
6242 " );\n",
6243 "\n",
6244 " rubberband_canvas.setAttribute('width', width);\n",
6245 " rubberband_canvas.setAttribute('height', height);\n",
6246 "\n",
6247 " // And update the size in Python. We ignore the initial 0/0 size\n",
6248 " // that occurs as the element is placed into the DOM, which should\n",
6249 " // otherwise not happen due to the minimum size styling.\n",
6250 " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n",
6251 " fig.request_resize(width, height);\n",
6252 " }\n",
6253 " }\n",
6254 " });\n",
6255 " this.resizeObserverInstance.observe(canvas_div);\n",
6256 "\n",
6257 " function on_mouse_event_closure(name) {\n",
6258 " return function (event) {\n",
6259 " return fig.mouse_event(event, name);\n",
6260 " };\n",
6261 " }\n",
6262 "\n",
6263 " rubberband_canvas.addEventListener(\n",
6264 " 'mousedown',\n",
6265 " on_mouse_event_closure('button_press')\n",
6266 " );\n",
6267 " rubberband_canvas.addEventListener(\n",
6268 " 'mouseup',\n",
6269 " on_mouse_event_closure('button_release')\n",
6270 " );\n",
6271 " // Throttle sequential mouse events to 1 every 20ms.\n",
6272 " rubberband_canvas.addEventListener(\n",
6273 " 'mousemove',\n",
6274 " on_mouse_event_closure('motion_notify')\n",
6275 " );\n",
6276 "\n",
6277 " rubberband_canvas.addEventListener(\n",
6278 " 'mouseenter',\n",
6279 " on_mouse_event_closure('figure_enter')\n",
6280 " );\n",
6281 " rubberband_canvas.addEventListener(\n",
6282 " 'mouseleave',\n",
6283 " on_mouse_event_closure('figure_leave')\n",
6284 " );\n",
6285 "\n",
6286 " canvas_div.addEventListener('wheel', function (event) {\n",
6287 " if (event.deltaY < 0) {\n",
6288 " event.step = 1;\n",
6289 " } else {\n",
6290 " event.step = -1;\n",
6291 " }\n",
6292 " on_mouse_event_closure('scroll')(event);\n",
6293 " });\n",
6294 "\n",
6295 " canvas_div.appendChild(canvas);\n",
6296 " canvas_div.appendChild(rubberband_canvas);\n",
6297 "\n",
6298 " this.rubberband_context = rubberband_canvas.getContext('2d');\n",
6299 " this.rubberband_context.strokeStyle = '#000000';\n",
6300 "\n",
6301 " this._resize_canvas = function (width, height, forward) {\n",
6302 " if (forward) {\n",
6303 " canvas_div.style.width = width + 'px';\n",
6304 " canvas_div.style.height = height + 'px';\n",
6305 " }\n",
6306 " };\n",
6307 "\n",
6308 " // Disable right mouse context menu.\n",
6309 " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
6310 " event.preventDefault();\n",
6311 " return false;\n",
6312 " });\n",
6313 "\n",
6314 " function set_focus() {\n",
6315 " canvas.focus();\n",
6316 " canvas_div.focus();\n",
6317 " }\n",
6318 "\n",
6319 " window.setTimeout(set_focus, 100);\n",
6320 "};\n",
6321 "\n",
6322 "mpl.figure.prototype._init_toolbar = function () {\n",
6323 " var fig = this;\n",
6324 "\n",
6325 " var toolbar = document.createElement('div');\n",
6326 " toolbar.classList = 'mpl-toolbar';\n",
6327 " this.root.appendChild(toolbar);\n",
6328 "\n",
6329 " function on_click_closure(name) {\n",
6330 " return function (_event) {\n",
6331 " return fig.toolbar_button_onclick(name);\n",
6332 " };\n",
6333 " }\n",
6334 "\n",
6335 " function on_mouseover_closure(tooltip) {\n",
6336 " return function (event) {\n",
6337 " if (!event.currentTarget.disabled) {\n",
6338 " return fig.toolbar_button_onmouseover(tooltip);\n",
6339 " }\n",
6340 " };\n",
6341 " }\n",
6342 "\n",
6343 " fig.buttons = {};\n",
6344 " var buttonGroup = document.createElement('div');\n",
6345 " buttonGroup.classList = 'mpl-button-group';\n",
6346 " for (var toolbar_ind in mpl.toolbar_items) {\n",
6347 " var name = mpl.toolbar_items[toolbar_ind][0];\n",
6348 " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
6349 " var image = mpl.toolbar_items[toolbar_ind][2];\n",
6350 " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
6351 "\n",
6352 " if (!name) {\n",
6353 " /* Instead of a spacer, we start a new button group. */\n",
6354 " if (buttonGroup.hasChildNodes()) {\n",
6355 " toolbar.appendChild(buttonGroup);\n",
6356 " }\n",
6357 " buttonGroup = document.createElement('div');\n",
6358 " buttonGroup.classList = 'mpl-button-group';\n",
6359 " continue;\n",
6360 " }\n",
6361 "\n",
6362 " var button = (fig.buttons[name] = document.createElement('button'));\n",
6363 " button.classList = 'mpl-widget';\n",
6364 " button.setAttribute('role', 'button');\n",
6365 " button.setAttribute('aria-disabled', 'false');\n",
6366 " button.addEventListener('click', on_click_closure(method_name));\n",
6367 " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
6368 "\n",
6369 " var icon_img = document.createElement('img');\n",
6370 " icon_img.src = '_images/' + image + '.png';\n",
6371 " icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
6372 " icon_img.alt = tooltip;\n",
6373 " button.appendChild(icon_img);\n",
6374 "\n",
6375 " buttonGroup.appendChild(button);\n",
6376 " }\n",
6377 "\n",
6378 " if (buttonGroup.hasChildNodes()) {\n",
6379 " toolbar.appendChild(buttonGroup);\n",
6380 " }\n",
6381 "\n",
6382 " var fmt_picker = document.createElement('select');\n",
6383 " fmt_picker.classList = 'mpl-widget';\n",
6384 " toolbar.appendChild(fmt_picker);\n",
6385 " this.format_dropdown = fmt_picker;\n",
6386 "\n",
6387 " for (var ind in mpl.extensions) {\n",
6388 " var fmt = mpl.extensions[ind];\n",
6389 " var option = document.createElement('option');\n",
6390 " option.selected = fmt === mpl.default_extension;\n",
6391 " option.innerHTML = fmt;\n",
6392 " fmt_picker.appendChild(option);\n",
6393 " }\n",
6394 "\n",
6395 " var status_bar = document.createElement('span');\n",
6396 " status_bar.classList = 'mpl-message';\n",
6397 " toolbar.appendChild(status_bar);\n",
6398 " this.message = status_bar;\n",
6399 "};\n",
6400 "\n",
6401 "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
6402 " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
6403 " // which will in turn request a refresh of the image.\n",
6404 " this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
6405 "};\n",
6406 "\n",
6407 "mpl.figure.prototype.send_message = function (type, properties) {\n",
6408 " properties['type'] = type;\n",
6409 " properties['figure_id'] = this.id;\n",
6410 " this.ws.send(JSON.stringify(properties));\n",
6411 "};\n",
6412 "\n",
6413 "mpl.figure.prototype.send_draw_message = function () {\n",
6414 " if (!this.waiting) {\n",
6415 " this.waiting = true;\n",
6416 " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
6417 " }\n",
6418 "};\n",
6419 "\n",
6420 "mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
6421 " var format_dropdown = fig.format_dropdown;\n",
6422 " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
6423 " fig.ondownload(fig, format);\n",
6424 "};\n",
6425 "\n",
6426 "mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
6427 " var size = msg['size'];\n",
6428 " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
6429 " fig._resize_canvas(size[0], size[1], msg['forward']);\n",
6430 " fig.send_message('refresh', {});\n",
6431 " }\n",
6432 "};\n",
6433 "\n",
6434 "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
6435 " var x0 = msg['x0'] / fig.ratio;\n",
6436 " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
6437 " var x1 = msg['x1'] / fig.ratio;\n",
6438 " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
6439 " x0 = Math.floor(x0) + 0.5;\n",
6440 " y0 = Math.floor(y0) + 0.5;\n",
6441 " x1 = Math.floor(x1) + 0.5;\n",
6442 " y1 = Math.floor(y1) + 0.5;\n",
6443 " var min_x = Math.min(x0, x1);\n",
6444 " var min_y = Math.min(y0, y1);\n",
6445 " var width = Math.abs(x1 - x0);\n",
6446 " var height = Math.abs(y1 - y0);\n",
6447 "\n",
6448 " fig.rubberband_context.clearRect(\n",
6449 " 0,\n",
6450 " 0,\n",
6451 " fig.canvas.width / fig.ratio,\n",
6452 " fig.canvas.height / fig.ratio\n",
6453 " );\n",
6454 "\n",
6455 " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
6456 "};\n",
6457 "\n",
6458 "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
6459 " // Updates the figure title.\n",
6460 " fig.header.textContent = msg['label'];\n",
6461 "};\n",
6462 "\n",
6463 "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
6464 " var cursor = msg['cursor'];\n",
6465 " switch (cursor) {\n",
6466 " case 0:\n",
6467 " cursor = 'pointer';\n",
6468 " break;\n",
6469 " case 1:\n",
6470 " cursor = 'default';\n",
6471 " break;\n",
6472 " case 2:\n",
6473 " cursor = 'crosshair';\n",
6474 " break;\n",
6475 " case 3:\n",
6476 " cursor = 'move';\n",
6477 " break;\n",
6478 " }\n",
6479 " fig.rubberband_canvas.style.cursor = cursor;\n",
6480 "};\n",
6481 "\n",
6482 "mpl.figure.prototype.handle_message = function (fig, msg) {\n",
6483 " fig.message.textContent = msg['message'];\n",
6484 "};\n",
6485 "\n",
6486 "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
6487 " // Request the server to send over a new figure.\n",
6488 " fig.send_draw_message();\n",
6489 "};\n",
6490 "\n",
6491 "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
6492 " fig.image_mode = msg['mode'];\n",
6493 "};\n",
6494 "\n",
6495 "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
6496 " for (var key in msg) {\n",
6497 " if (!(key in fig.buttons)) {\n",
6498 " continue;\n",
6499 " }\n",
6500 " fig.buttons[key].disabled = !msg[key];\n",
6501 " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
6502 " }\n",
6503 "};\n",
6504 "\n",
6505 "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
6506 " if (msg['mode'] === 'PAN') {\n",
6507 " fig.buttons['Pan'].classList.add('active');\n",
6508 " fig.buttons['Zoom'].classList.remove('active');\n",
6509 " } else if (msg['mode'] === 'ZOOM') {\n",
6510 " fig.buttons['Pan'].classList.remove('active');\n",
6511 " fig.buttons['Zoom'].classList.add('active');\n",
6512 " } else {\n",
6513 " fig.buttons['Pan'].classList.remove('active');\n",
6514 " fig.buttons['Zoom'].classList.remove('active');\n",
6515 " }\n",
6516 "};\n",
6517 "\n",
6518 "mpl.figure.prototype.updated_canvas_event = function () {\n",
6519 " // Called whenever the canvas gets updated.\n",
6520 " this.send_message('ack', {});\n",
6521 "};\n",
6522 "\n",
6523 "// A function to construct a web socket function for onmessage handling.\n",
6524 "// Called in the figure constructor.\n",
6525 "mpl.figure.prototype._make_on_message_function = function (fig) {\n",
6526 " return function socket_on_message(evt) {\n",
6527 " if (evt.data instanceof Blob) {\n",
6528 " /* FIXME: We get \"Resource interpreted as Image but\n",
6529 " * transferred with MIME type text/plain:\" errors on\n",
6530 " * Chrome. But how to set the MIME type? It doesn't seem\n",
6531 " * to be part of the websocket stream */\n",
6532 " evt.data.type = 'image/png';\n",
6533 "\n",
6534 " /* Free the memory for the previous frames */\n",
6535 " if (fig.imageObj.src) {\n",
6536 " (window.URL || window.webkitURL).revokeObjectURL(\n",
6537 " fig.imageObj.src\n",
6538 " );\n",
6539 " }\n",
6540 "\n",
6541 " fig.imageObj.src = (window.URL ||