Last active
November 5, 2016 19:01
-
-
Save JonathanReeve/747a7f6dd0be0771c9728b12321253b7 to your computer and use it in GitHub Desktop.
Gatsby Characters PCA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# PCA of Character Speech in _The Great Gatsby_" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# For XML parsing. \n", | |
"from lxml import etree\n", | |
"\n", | |
"# For counting things\n", | |
"from collections import Counter\n", | |
"\n", | |
"# For PCA\n", | |
"from sklearn.decomposition import PCA\n", | |
"\n", | |
"# For Latent Semantic Analysis\n", | |
"from sklearn.decomposition import TruncatedSVD\n", | |
"\n", | |
"# For tokenizing, counting, etc. \n", | |
"from sklearn.feature_extraction.text import CountVectorizer\n", | |
"from sklearn.feature_extraction.text import TfidfVectorizer\n", | |
"\n", | |
"# For data processing\n", | |
"import pandas as pd\n", | |
"\n", | |
"# Stuff for plotting pretty charts\n", | |
"import matplotlib.pyplot as plt\n", | |
"from mpl_toolkits.mplot3d import Axes3D\n", | |
"from mpl_toolkits.mplot3d import proj3d\n", | |
"%matplotlib notebook\n", | |
"#plt.style.use('ggplot')\n", | |
"#plt.rcParams['figure.figsize'] = (14,8)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Grab and parse the TEI XML. \n", | |
"tree = etree.parse('gatsby/gatsby.xml')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"['Gatsby',\n", | |
" 'Nick',\n", | |
" 'Tom',\n", | |
" 'Daisy',\n", | |
" 'Jordan',\n", | |
" 'Wolfsheim',\n", | |
" 'Wilson',\n", | |
" 'Myrtle',\n", | |
" 'Owl-Eyes',\n", | |
" 'Michaelis']" | |
] | |
}, | |
"execution_count": 28, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Get all utterances. \n", | |
"elems = tree.findall(\".//said[@who]\")\n", | |
"\n", | |
"# Make a list of all characters\n", | |
"allChars = [elem.attrib['who'] for elem in elems]\n", | |
"\n", | |
"# Get number of utterances for each character. \n", | |
"charsCounts = Counter(allChars)\n", | |
"\n", | |
"# Sort by number of utterances. \n", | |
"sortedChars = sorted(charsCounts, key=charsCounts.get, reverse=True)\n", | |
"\n", | |
"# Grab top ten characters by number of utterances\n", | |
"mainChars = sortedChars[:10]\n", | |
"\n", | |
"# Let's see what it looks like. \n", | |
"mainChars" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class Character(): \n", | |
" \"\"\" Extracts character speech from the parsed text. \"\"\"\n", | |
" def __init__(self, tree, name): \n", | |
" \"\"\" \n", | |
" Takes an etree tree object as input, as well as \n", | |
" the character's name. \n", | |
" \"\"\"\n", | |
" xpath = \".//said[@who='%s']\" % name\n", | |
" elements = tree.findall(xpath)\n", | |
" self.lines = [element.text for element in elements]\n", | |
" # Remove quotation marks. \n", | |
" self.lines = [line.replace('\"', '') for line in self.lines]\n", | |
" # Put it all back together. \n", | |
" self.glob = ' '.join(self.lines)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# Get character speech for the main characters. \n", | |
"characters = [Character(tree, char).glob for char in mainChars]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/javascript": [ | |
"/* Put everything inside the global mpl namespace */\n", | |
"window.mpl = {};\n", | |
"\n", | |
"mpl.get_websocket_type = function() {\n", | |
" if (typeof(WebSocket) !== 'undefined') {\n", | |
" return WebSocket;\n", | |
" } else if (typeof(MozWebSocket) !== 'undefined') {\n", | |
" return MozWebSocket;\n", | |
" } else {\n", | |
" alert('Your browser does not have WebSocket support.' +\n", | |
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", | |
" 'Firefox 4 and 5 are also supported but you ' +\n", | |
" 'have to enable WebSockets in about:config.');\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", | |
" this.id = figure_id;\n", | |
"\n", | |
" this.ws = websocket;\n", | |
"\n", | |
" this.supports_binary = (this.ws.binaryType != undefined);\n", | |
"\n", | |
" if (!this.supports_binary) {\n", | |
" var warnings = document.getElementById(\"mpl-warnings\");\n", | |
" if (warnings) {\n", | |
" warnings.style.display = 'block';\n", | |
" warnings.textContent = (\n", | |
" \"This browser does not support binary websocket messages. \" +\n", | |
" \"Performance may be slow.\");\n", | |
" }\n", | |
" }\n", | |
"\n", | |
" this.imageObj = new Image();\n", | |
"\n", | |
" this.context = undefined;\n", | |
" this.message = undefined;\n", | |
" this.canvas = undefined;\n", | |
" this.rubberband_canvas = undefined;\n", | |
" this.rubberband_context = undefined;\n", | |
" this.format_dropdown = undefined;\n", | |
"\n", | |
" this.image_mode = 'full';\n", | |
"\n", | |
" this.root = $('<div/>');\n", | |
" this._root_extra_style(this.root)\n", | |
" this.root.attr('style', 'display: inline-block');\n", | |
"\n", | |
" $(parent_element).append(this.root);\n", | |
"\n", | |
" this._init_header(this);\n", | |
" this._init_canvas(this);\n", | |
" this._init_toolbar(this);\n", | |
"\n", | |
" var fig = this;\n", | |
"\n", | |
" this.waiting = false;\n", | |
"\n", | |
" this.ws.onopen = function () {\n", | |
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", | |
" fig.send_message(\"send_image_mode\", {});\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" }\n", | |
"\n", | |
" this.imageObj.onload = function() {\n", | |
" if (fig.image_mode == 'full') {\n", | |
" // Full images could contain transparency (where diff images\n", | |
" // almost always do), so we need to clear the canvas so that\n", | |
" // there is no ghosting.\n", | |
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", | |
" }\n", | |
" fig.context.drawImage(fig.imageObj, 0, 0);\n", | |
" };\n", | |
"\n", | |
" this.imageObj.onunload = function() {\n", | |
" this.ws.close();\n", | |
" }\n", | |
"\n", | |
" this.ws.onmessage = this._make_on_message_function(this);\n", | |
"\n", | |
" this.ondownload = ondownload;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_header = function() {\n", | |
" var titlebar = $(\n", | |
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", | |
" 'ui-helper-clearfix\"/>');\n", | |
" var titletext = $(\n", | |
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", | |
" 'text-align: center; padding: 3px;\"/>');\n", | |
" titlebar.append(titletext)\n", | |
" this.root.append(titlebar);\n", | |
" this.header = titletext[0];\n", | |
"}\n", | |
"\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_canvas = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var canvas_div = $('<div/>');\n", | |
"\n", | |
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", | |
"\n", | |
" function canvas_keyboard_event(event) {\n", | |
" return fig.key_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" canvas_div.keydown('key_press', canvas_keyboard_event);\n", | |
" canvas_div.keyup('key_release', canvas_keyboard_event);\n", | |
" this.canvas_div = canvas_div\n", | |
" this._canvas_extra_style(canvas_div)\n", | |
" this.root.append(canvas_div);\n", | |
"\n", | |
" var canvas = $('<canvas/>');\n", | |
" canvas.addClass('mpl-canvas');\n", | |
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", | |
"\n", | |
" this.canvas = canvas[0];\n", | |
" this.context = canvas[0].getContext(\"2d\");\n", | |
"\n", | |
" var rubberband = $('<canvas/>');\n", | |
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", | |
"\n", | |
" var pass_mouse_events = true;\n", | |
"\n", | |
" canvas_div.resizable({\n", | |
" start: function(event, ui) {\n", | |
" pass_mouse_events = false;\n", | |
" },\n", | |
" resize: function(event, ui) {\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" stop: function(event, ui) {\n", | |
" pass_mouse_events = true;\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" });\n", | |
"\n", | |
" function mouse_event_fn(event) {\n", | |
" if (pass_mouse_events)\n", | |
" return fig.mouse_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" rubberband.mousedown('button_press', mouse_event_fn);\n", | |
" rubberband.mouseup('button_release', mouse_event_fn);\n", | |
" // Throttle sequential mouse events to 1 every 20ms.\n", | |
" rubberband.mousemove('motion_notify', mouse_event_fn);\n", | |
"\n", | |
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n", | |
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n", | |
"\n", | |
" canvas_div.on(\"wheel\", function (event) {\n", | |
" event = event.originalEvent;\n", | |
" event['data'] = 'scroll'\n", | |
" if (event.deltaY < 0) {\n", | |
" event.step = 1;\n", | |
" } else {\n", | |
" event.step = -1;\n", | |
" }\n", | |
" mouse_event_fn(event);\n", | |
" });\n", | |
"\n", | |
" canvas_div.append(canvas);\n", | |
" canvas_div.append(rubberband);\n", | |
"\n", | |
" this.rubberband = rubberband;\n", | |
" this.rubberband_canvas = rubberband[0];\n", | |
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n", | |
" this.rubberband_context.strokeStyle = \"#000000\";\n", | |
"\n", | |
" this._resize_canvas = function(width, height) {\n", | |
" // Keep the size of the canvas, canvas container, and rubber band\n", | |
" // canvas in synch.\n", | |
" canvas_div.css('width', width)\n", | |
" canvas_div.css('height', height)\n", | |
"\n", | |
" canvas.attr('width', width);\n", | |
" canvas.attr('height', height);\n", | |
"\n", | |
" rubberband.attr('width', width);\n", | |
" rubberband.attr('height', height);\n", | |
" }\n", | |
"\n", | |
" // Set the figure to an initial 600x600px, this will subsequently be updated\n", | |
" // upon first draw.\n", | |
" this._resize_canvas(600, 600);\n", | |
"\n", | |
" // Disable right mouse context menu.\n", | |
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", | |
" return false;\n", | |
" });\n", | |
"\n", | |
" function set_focus () {\n", | |
" canvas.focus();\n", | |
" canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" window.setTimeout(set_focus, 100);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items) {\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) {\n", | |
" // put a spacer in here.\n", | |
" continue;\n", | |
" }\n", | |
" var button = $('<button/>');\n", | |
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", | |
" 'ui-button-icon-only');\n", | |
" button.attr('role', 'button');\n", | |
" button.attr('aria-disabled', 'false');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
"\n", | |
" var icon_img = $('<span/>');\n", | |
" icon_img.addClass('ui-button-icon-primary ui-icon');\n", | |
" icon_img.addClass(image);\n", | |
" icon_img.addClass('ui-corner-all');\n", | |
"\n", | |
" var tooltip_span = $('<span/>');\n", | |
" tooltip_span.addClass('ui-button-text');\n", | |
" tooltip_span.html(tooltip);\n", | |
"\n", | |
" button.append(icon_img);\n", | |
" button.append(tooltip_span);\n", | |
"\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" var fmt_picker_span = $('<span/>');\n", | |
"\n", | |
" var fmt_picker = $('<select/>');\n", | |
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", | |
" fmt_picker_span.append(fmt_picker);\n", | |
" nav_element.append(fmt_picker_span);\n", | |
" this.format_dropdown = fmt_picker[0];\n", | |
"\n", | |
" for (var ind in mpl.extensions) {\n", | |
" var fmt = mpl.extensions[ind];\n", | |
" var option = $(\n", | |
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", | |
" fmt_picker.append(option)\n", | |
" }\n", | |
"\n", | |
" // Add hover states to the ui-buttons\n", | |
" $( \".ui-button\" ).hover(\n", | |
" function() { $(this).addClass(\"ui-state-hover\");},\n", | |
" function() { $(this).removeClass(\"ui-state-hover\");}\n", | |
" );\n", | |
"\n", | |
" var status_bar = $('<span class=\"mpl-message\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", | |
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", | |
" // which will in turn request a refresh of the image.\n", | |
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_message = function(type, properties) {\n", | |
" properties['type'] = type;\n", | |
" properties['figure_id'] = this.id;\n", | |
" this.ws.send(JSON.stringify(properties));\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_draw_message = function() {\n", | |
" if (!this.waiting) {\n", | |
" this.waiting = true;\n", | |
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" var format_dropdown = fig.format_dropdown;\n", | |
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", | |
" fig.ondownload(fig, format);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n", | |
" var size = msg['size'];\n", | |
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", | |
" fig._resize_canvas(size[0], size[1]);\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", | |
" var x0 = msg['x0'];\n", | |
" var y0 = fig.canvas.height - msg['y0'];\n", | |
" var x1 = msg['x1'];\n", | |
" var y1 = fig.canvas.height - msg['y1'];\n", | |
" x0 = Math.floor(x0) + 0.5;\n", | |
" y0 = Math.floor(y0) + 0.5;\n", | |
" x1 = Math.floor(x1) + 0.5;\n", | |
" y1 = Math.floor(y1) + 0.5;\n", | |
" var min_x = Math.min(x0, x1);\n", | |
" var min_y = Math.min(y0, y1);\n", | |
" var width = Math.abs(x1 - x0);\n", | |
" var height = Math.abs(y1 - y0);\n", | |
"\n", | |
" fig.rubberband_context.clearRect(\n", | |
" 0, 0, fig.canvas.width, fig.canvas.height);\n", | |
"\n", | |
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n", | |
" // Updates the figure title.\n", | |
" fig.header.textContent = msg['label'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n", | |
" var cursor = msg['cursor'];\n", | |
" switch(cursor)\n", | |
" {\n", | |
" case 0:\n", | |
" cursor = 'pointer';\n", | |
" break;\n", | |
" case 1:\n", | |
" cursor = 'default';\n", | |
" break;\n", | |
" case 2:\n", | |
" cursor = 'crosshair';\n", | |
" break;\n", | |
" case 3:\n", | |
" cursor = 'move';\n", | |
" break;\n", | |
" }\n", | |
" fig.rubberband_canvas.style.cursor = cursor;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_message = function(fig, msg) {\n", | |
" fig.message.textContent = msg['message'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n", | |
" // Request the server to send over a new figure.\n", | |
" fig.send_draw_message();\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n", | |
" fig.image_mode = msg['mode'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Called whenever the canvas gets updated.\n", | |
" this.send_message(\"ack\", {});\n", | |
"}\n", | |
"\n", | |
"// A function to construct a web socket function for onmessage handling.\n", | |
"// Called in the figure constructor.\n", | |
"mpl.figure.prototype._make_on_message_function = function(fig) {\n", | |
" return function socket_on_message(evt) {\n", | |
" if (evt.data instanceof Blob) {\n", | |
" /* FIXME: We get \"Resource interpreted as Image but\n", | |
" * transferred with MIME type text/plain:\" errors on\n", | |
" * Chrome. But how to set the MIME type? It doesn't seem\n", | |
" * to be part of the websocket stream */\n", | |
" evt.data.type = \"image/png\";\n", | |
"\n", | |
" /* Free the memory for the previous frames */\n", | |
" if (fig.imageObj.src) {\n", | |
" (window.URL || window.webkitURL).revokeObjectURL(\n", | |
" fig.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", | |
" evt.data);\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n", | |
" fig.imageObj.src = evt.data;\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var msg = JSON.parse(evt.data);\n", | |
" var msg_type = msg['type'];\n", | |
"\n", | |
" // Call the \"handle_{type}\" callback, which takes\n", | |
" // the figure and JSON message as its only arguments.\n", | |
" try {\n", | |
" var callback = fig[\"handle_\" + msg_type];\n", | |
" } catch (e) {\n", | |
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" if (callback) {\n", | |
" try {\n", | |
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", | |
" callback(fig, msg);\n", | |
" } catch (e) {\n", | |
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n", | |
" }\n", | |
" }\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", | |
"mpl.findpos = function(e) {\n", | |
" //this section is from http://www.quirksmode.org/js/events_properties.html\n", | |
" var targ;\n", | |
" if (!e)\n", | |
" e = window.event;\n", | |
" if (e.target)\n", | |
" targ = e.target;\n", | |
" else if (e.srcElement)\n", | |
" targ = e.srcElement;\n", | |
" if (targ.nodeType == 3) // defeat Safari bug\n", | |
" targ = targ.parentNode;\n", | |
"\n", | |
" // jQuery normalizes the pageX and pageY\n", | |
" // pageX,Y are the mouse positions relative to the document\n", | |
" // offset() returns the position of the element relative to the document\n", | |
" var x = e.pageX - $(targ).offset().left;\n", | |
" var y = e.pageY - $(targ).offset().top;\n", | |
"\n", | |
" return {\"x\": x, \"y\": y};\n", | |
"};\n", | |
"\n", | |
"/*\n", | |
" * return a copy of an object with only non-object keys\n", | |
" * we need this to avoid circular references\n", | |
" * http://stackoverflow.com/a/24161582/3208463\n", | |
" */\n", | |
"function simpleKeys (original) {\n", | |
" return Object.keys(original).reduce(function (obj, key) {\n", | |
" if (typeof original[key] !== 'object')\n", | |
" obj[key] = original[key]\n", | |
" return obj;\n", | |
" }, {});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.mouse_event = function(event, name) {\n", | |
" var canvas_pos = mpl.findpos(event)\n", | |
"\n", | |
" if (name === 'button_press')\n", | |
" {\n", | |
" this.canvas.focus();\n", | |
" this.canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" var x = canvas_pos.x;\n", | |
" var y = canvas_pos.y;\n", | |
"\n", | |
" this.send_message(name, {x: x, y: y, button: event.button,\n", | |
" step: event.step,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
"\n", | |
" /* This prevents the web browser from automatically changing to\n", | |
" * the text insertion cursor when the button is pressed. We want\n", | |
" * to control all of the cursor setting manually through the\n", | |
" * 'cursor' event from matplotlib */\n", | |
" event.preventDefault();\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" // Handle any extra behaviour associated with a key event\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.key_event = function(event, name) {\n", | |
"\n", | |
" // Prevent repeat events\n", | |
" if (name == 'key_press')\n", | |
" {\n", | |
" if (event.which === this._key)\n", | |
" return;\n", | |
" else\n", | |
" this._key = event.which;\n", | |
" }\n", | |
" if (name == 'key_release')\n", | |
" this._key = null;\n", | |
"\n", | |
" var value = '';\n", | |
" if (event.ctrlKey && event.which != 17)\n", | |
" value += \"ctrl+\";\n", | |
" if (event.altKey && event.which != 18)\n", | |
" value += \"alt+\";\n", | |
" if (event.shiftKey && event.which != 16)\n", | |
" value += \"shift+\";\n", | |
"\n", | |
" value += 'k';\n", | |
" value += event.which.toString();\n", | |
"\n", | |
" this._key_event_extra(event, name);\n", | |
"\n", | |
" this.send_message(name, {key: value,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", | |
" if (name == 'download') {\n", | |
" this.handle_save(this, null);\n", | |
" } else {\n", | |
" this.send_message(\"toolbar_button\", {name: name});\n", | |
" }\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", | |
" this.message.textContent = tooltip;\n", | |
"};\n", | |
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", | |
"\n", | |
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", | |
"\n", | |
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", | |
" // Create a \"websocket\"-like object which calls the given IPython comm\n", | |
" // object with the appropriate methods. Currently this is a non binary\n", | |
" // socket, so there is still some room for performance tuning.\n", | |
" var ws = {};\n", | |
"\n", | |
" ws.close = function() {\n", | |
" comm.close()\n", | |
" };\n", | |
" ws.send = function(m) {\n", | |
" //console.log('sending', m);\n", | |
" comm.send(m);\n", | |
" };\n", | |
" // Register the callback with on_msg.\n", | |
" comm.on_msg(function(msg) {\n", | |
" //console.log('receiving', msg['content']['data'], msg);\n", | |
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", | |
" ws.onmessage(msg['content']['data'])\n", | |
" });\n", | |
" return ws;\n", | |
"}\n", | |
"\n", | |
"mpl.mpl_figure_comm = function(comm, msg) {\n", | |
" // This is the function which gets called when the mpl process\n", | |
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", | |
"\n", | |
" var id = msg.content.data.id;\n", | |
" // Get hold of the div created by the display call when the Comm\n", | |
" // socket was opened in Python.\n", | |
" var element = $(\"#\" + id);\n", | |
" var ws_proxy = comm_websocket_adapter(comm)\n", | |
"\n", | |
" function ondownload(figure, format) {\n", | |
" window.open(figure.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" var fig = new mpl.figure(id, ws_proxy,\n", | |
" ondownload,\n", | |
" element.get(0));\n", | |
"\n", | |
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", | |
" // web socket which is closed, not our websocket->open comm proxy.\n", | |
" ws_proxy.onopen();\n", | |
"\n", | |
" fig.parent_element = element.get(0);\n", | |
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", | |
" if (!fig.cell_info) {\n", | |
" console.error(\"Failed to find cell for figure\", id, fig);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var output_index = fig.cell_info[2]\n", | |
" var cell = fig.cell_info[0];\n", | |
"\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", | |
" fig.root.unbind('remove')\n", | |
"\n", | |
" // Update the output cell to use the data from the current canvas.\n", | |
" fig.push_to_output();\n", | |
" var dataURL = fig.canvas.toDataURL();\n", | |
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n", | |
" // the notebook keyboard shortcuts fail.\n", | |
" IPython.keyboard_manager.enable()\n", | |
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n", | |
" fig.close_ws(fig, msg);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.close_ws = function(fig, msg){\n", | |
" fig.send_message('closing', msg);\n", | |
" // fig.ws.close()\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n", | |
" // Turn the data on the canvas into data in the output cell.\n", | |
" var dataURL = this.canvas.toDataURL();\n", | |
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Tell IPython that the notebook contents must change.\n", | |
" IPython.notebook.set_dirty(true);\n", | |
" this.send_message(\"ack\", {});\n", | |
" var fig = this;\n", | |
" // Wait a second, then push the new image to the DOM so\n", | |
" // that it is saved nicely (might be nice to debounce this).\n", | |
" setTimeout(function () { fig.push_to_output() }, 1000);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items){\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) { continue; };\n", | |
"\n", | |
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" // Add the status bar.\n", | |
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"\n", | |
" // Add the close button to the window.\n", | |
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n", | |
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n", | |
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", | |
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n", | |
" buttongrp.append(button);\n", | |
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", | |
" titlebar.prepend(buttongrp);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(el){\n", | |
" var fig = this\n", | |
" el.on(\"remove\", function(){\n", | |
"\tfig.close_ws(fig, {});\n", | |
" });\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(el){\n", | |
" // this is important to make the div 'focusable\n", | |
" el.attr('tabindex', 0)\n", | |
" // reach out to IPython and tell the keyboard manager to turn it's self\n", | |
" // off when our div gets focus\n", | |
"\n", | |
" // location in version 3\n", | |
" if (IPython.notebook.keyboard_manager) {\n", | |
" IPython.notebook.keyboard_manager.register_events(el);\n", | |
" }\n", | |
" else {\n", | |
" // location in version 2\n", | |
" IPython.keyboard_manager.register_events(el);\n", | |
" }\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" var manager = IPython.notebook.keyboard_manager;\n", | |
" if (!manager)\n", | |
" manager = IPython.keyboard_manager;\n", | |
"\n", | |
" // Check for shift+enter\n", | |
" if (event.shiftKey && event.which == 13) {\n", | |
" this.canvas_div.blur();\n", | |
" // select the cell after this one\n", | |
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", | |
" IPython.notebook.select(index + 1);\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" fig.ondownload(fig, null);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.find_output_cell = function(html_output) {\n", | |
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", | |
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", | |
" // IPython event is triggered only after the cells have been serialised, which for\n", | |
" // our purposes (turning an active figure into a static one), is too late.\n", | |
" var cells = IPython.notebook.get_cells();\n", | |
" var ncells = cells.length;\n", | |
" for (var i=0; i<ncells; i++) {\n", | |
" var cell = cells[i];\n", | |
" if (cell.cell_type === 'code'){\n", | |
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", | |
" var data = cell.output_area.outputs[j];\n", | |
" if (data.data) {\n", | |
" // IPython >= 3 moved mimebundle to data attribute of output\n", | |
" data = data.data;\n", | |
" }\n", | |
" if (data['text/html'] == html_output) {\n", | |
" return [cell, data, j];\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"// Register the function which deals with the matplotlib target/channel.\n", | |
"// The kernel may be null if the page has been refreshed.\n", | |
"if (IPython.notebook.kernel != null) {\n", | |
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", | |
"}\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"<img src=\"data:image/png;base64,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\">" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"<matplotlib.axes._subplots.AxesSubplot at 0x7fb6d65fb6a0>" | |
] | |
}, | |
"execution_count": 31, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Compare lengths of character speech, so that we compare the same word frequencies. \n", | |
"s = pd.Series([len(character) for character in characters], index=mainChars)\n", | |
"s.plot(kind=\"bar\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Let's just use the first five characters, actually, \n", | |
"# since they have the most text. \n", | |
"mainChars = mainChars[:5]\n", | |
"\n", | |
"# Re-extract the character text for each. \n", | |
"characters = [Character(tree, char).glob for char in mainChars]\n", | |
"\n", | |
"# And let's chop off each at 7000, \n", | |
"# so that we're comparing the same amount of text for each. \n", | |
"characters = [character[:7000] for character in characters]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 33, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# Use CountVectorizer to tokenize and count words in all texts. \n", | |
"cv = CountVectorizer()\n", | |
"out = cv.fit_transform(characters).todense()\n", | |
"\n", | |
"# Put it into a Pandas DataFrame\n", | |
"df = pd.DataFrame(out)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>1919</th>\n", | |
" <th>abandoned</th>\n", | |
" <th>able</th>\n", | |
" <th>about</th>\n", | |
" <th>absolute</th>\n", | |
" <th>absolutely</th>\n", | |
" <th>abstracted</th>\n", | |
" <th>accepted</th>\n", | |
" <th>accident</th>\n", | |
" <th>accidentally</th>\n", | |
" <th>...</th>\n", | |
" <th>year</th>\n", | |
" <th>years</th>\n", | |
" <th>yellowy</th>\n", | |
" <th>yes</th>\n", | |
" <th>york</th>\n", | |
" <th>you</th>\n", | |
" <th>young</th>\n", | |
" <th>your</th>\n", | |
" <th>yours</th>\n", | |
" <th>yourself</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>Gatsby</th>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>10</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>1</td>\n", | |
" <td>4</td>\n", | |
" <td>0</td>\n", | |
" <td>3</td>\n", | |
" <td>1</td>\n", | |
" <td>52</td>\n", | |
" <td>1</td>\n", | |
" <td>5</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>Nick</th>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>1</td>\n", | |
" <td>12</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>6</td>\n", | |
" <td>2</td>\n", | |
" <td>61</td>\n", | |
" <td>0</td>\n", | |
" <td>6</td>\n", | |
" <td>0</td>\n", | |
" <td>2</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>Tom</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>10</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>2</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>2</td>\n", | |
" <td>1</td>\n", | |
" <td>64</td>\n", | |
" <td>0</td>\n", | |
" <td>5</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>Daisy</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>4</td>\n", | |
" <td>3</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>...</td>\n", | |
" <td>3</td>\n", | |
" <td>4</td>\n", | |
" <td>1</td>\n", | |
" <td>2</td>\n", | |
" <td>2</td>\n", | |
" <td>58</td>\n", | |
" <td>1</td>\n", | |
" <td>5</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>Jordan</th>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>2</td>\n", | |
" <td>0</td>\n", | |
" <td>3</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>...</td>\n", | |
" <td>2</td>\n", | |
" <td>2</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" <td>2</td>\n", | |
" <td>19</td>\n", | |
" <td>5</td>\n", | |
" <td>1</td>\n", | |
" <td>0</td>\n", | |
" <td>0</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5 rows × 1255 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" 1919 abandoned able about absolute absolutely abstracted \\\n", | |
"Gatsby 1 0 1 10 0 1 0 \n", | |
"Nick 0 1 1 12 0 0 0 \n", | |
"Tom 0 0 0 10 0 0 0 \n", | |
"Daisy 0 0 0 4 3 1 0 \n", | |
"Jordan 0 0 0 2 0 3 1 \n", | |
"\n", | |
" accepted accident accidentally ... year years yellowy yes \\\n", | |
"Gatsby 1 0 0 ... 1 4 0 3 \n", | |
"Nick 0 0 0 ... 0 0 0 6 \n", | |
"Tom 0 0 0 ... 2 0 0 2 \n", | |
"Daisy 0 0 1 ... 3 4 1 2 \n", | |
"Jordan 0 1 0 ... 2 2 0 0 \n", | |
"\n", | |
" york you young your yours yourself \n", | |
"Gatsby 1 52 1 5 0 0 \n", | |
"Nick 2 61 0 6 0 2 \n", | |
"Tom 1 64 0 5 1 0 \n", | |
"Daisy 2 58 1 5 0 1 \n", | |
"Jordan 2 19 5 1 0 0 \n", | |
"\n", | |
"[5 rows x 1255 columns]" | |
] | |
}, | |
"execution_count": 34, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Just for fun, let's take a peek at that data frame. \n", | |
"# First, give it meaningful column and row names. \n", | |
"df.columns = [cv.get_feature_names()]\n", | |
"df.index = mainChars\n", | |
"df" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 35, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# Now the PCA magic. \n", | |
"pca = PCA(n_components=3)\n", | |
"pcaed = pca.fit_transform(df)\n", | |
"pcaDF = pd.DataFrame(pcaed)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 36, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Plot the results. \n", | |
"def plotResults(df, labels): \n", | |
" fig = plt.figure()\n", | |
" ax = fig.add_subplot(111, projection='3d')\n", | |
" ax.scatter(df[0], df[1], df[2], marker='o')\n", | |
" for i, label in enumerate(labels):\n", | |
" #plt.annotate(label, (df.loc[i][0], df.loc[i][1], df.loc[i][2]))\n", | |
" ax.text(df.loc[i][0], df.loc[i][1], df.loc[i][2], label)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/javascript": [ | |
"/* Put everything inside the global mpl namespace */\n", | |
"window.mpl = {};\n", | |
"\n", | |
"mpl.get_websocket_type = function() {\n", | |
" if (typeof(WebSocket) !== 'undefined') {\n", | |
" return WebSocket;\n", | |
" } else if (typeof(MozWebSocket) !== 'undefined') {\n", | |
" return MozWebSocket;\n", | |
" } else {\n", | |
" alert('Your browser does not have WebSocket support.' +\n", | |
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", | |
" 'Firefox 4 and 5 are also supported but you ' +\n", | |
" 'have to enable WebSockets in about:config.');\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", | |
" this.id = figure_id;\n", | |
"\n", | |
" this.ws = websocket;\n", | |
"\n", | |
" this.supports_binary = (this.ws.binaryType != undefined);\n", | |
"\n", | |
" if (!this.supports_binary) {\n", | |
" var warnings = document.getElementById(\"mpl-warnings\");\n", | |
" if (warnings) {\n", | |
" warnings.style.display = 'block';\n", | |
" warnings.textContent = (\n", | |
" \"This browser does not support binary websocket messages. \" +\n", | |
" \"Performance may be slow.\");\n", | |
" }\n", | |
" }\n", | |
"\n", | |
" this.imageObj = new Image();\n", | |
"\n", | |
" this.context = undefined;\n", | |
" this.message = undefined;\n", | |
" this.canvas = undefined;\n", | |
" this.rubberband_canvas = undefined;\n", | |
" this.rubberband_context = undefined;\n", | |
" this.format_dropdown = undefined;\n", | |
"\n", | |
" this.image_mode = 'full';\n", | |
"\n", | |
" this.root = $('<div/>');\n", | |
" this._root_extra_style(this.root)\n", | |
" this.root.attr('style', 'display: inline-block');\n", | |
"\n", | |
" $(parent_element).append(this.root);\n", | |
"\n", | |
" this._init_header(this);\n", | |
" this._init_canvas(this);\n", | |
" this._init_toolbar(this);\n", | |
"\n", | |
" var fig = this;\n", | |
"\n", | |
" this.waiting = false;\n", | |
"\n", | |
" this.ws.onopen = function () {\n", | |
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", | |
" fig.send_message(\"send_image_mode\", {});\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" }\n", | |
"\n", | |
" this.imageObj.onload = function() {\n", | |
" if (fig.image_mode == 'full') {\n", | |
" // Full images could contain transparency (where diff images\n", | |
" // almost always do), so we need to clear the canvas so that\n", | |
" // there is no ghosting.\n", | |
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", | |
" }\n", | |
" fig.context.drawImage(fig.imageObj, 0, 0);\n", | |
" };\n", | |
"\n", | |
" this.imageObj.onunload = function() {\n", | |
" this.ws.close();\n", | |
" }\n", | |
"\n", | |
" this.ws.onmessage = this._make_on_message_function(this);\n", | |
"\n", | |
" this.ondownload = ondownload;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_header = function() {\n", | |
" var titlebar = $(\n", | |
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", | |
" 'ui-helper-clearfix\"/>');\n", | |
" var titletext = $(\n", | |
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", | |
" 'text-align: center; padding: 3px;\"/>');\n", | |
" titlebar.append(titletext)\n", | |
" this.root.append(titlebar);\n", | |
" this.header = titletext[0];\n", | |
"}\n", | |
"\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_canvas = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var canvas_div = $('<div/>');\n", | |
"\n", | |
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", | |
"\n", | |
" function canvas_keyboard_event(event) {\n", | |
" return fig.key_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" canvas_div.keydown('key_press', canvas_keyboard_event);\n", | |
" canvas_div.keyup('key_release', canvas_keyboard_event);\n", | |
" this.canvas_div = canvas_div\n", | |
" this._canvas_extra_style(canvas_div)\n", | |
" this.root.append(canvas_div);\n", | |
"\n", | |
" var canvas = $('<canvas/>');\n", | |
" canvas.addClass('mpl-canvas');\n", | |
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", | |
"\n", | |
" this.canvas = canvas[0];\n", | |
" this.context = canvas[0].getContext(\"2d\");\n", | |
"\n", | |
" var rubberband = $('<canvas/>');\n", | |
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", | |
"\n", | |
" var pass_mouse_events = true;\n", | |
"\n", | |
" canvas_div.resizable({\n", | |
" start: function(event, ui) {\n", | |
" pass_mouse_events = false;\n", | |
" },\n", | |
" resize: function(event, ui) {\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" stop: function(event, ui) {\n", | |
" pass_mouse_events = true;\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" });\n", | |
"\n", | |
" function mouse_event_fn(event) {\n", | |
" if (pass_mouse_events)\n", | |
" return fig.mouse_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" rubberband.mousedown('button_press', mouse_event_fn);\n", | |
" rubberband.mouseup('button_release', mouse_event_fn);\n", | |
" // Throttle sequential mouse events to 1 every 20ms.\n", | |
" rubberband.mousemove('motion_notify', mouse_event_fn);\n", | |
"\n", | |
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n", | |
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n", | |
"\n", | |
" canvas_div.on(\"wheel\", function (event) {\n", | |
" event = event.originalEvent;\n", | |
" event['data'] = 'scroll'\n", | |
" if (event.deltaY < 0) {\n", | |
" event.step = 1;\n", | |
" } else {\n", | |
" event.step = -1;\n", | |
" }\n", | |
" mouse_event_fn(event);\n", | |
" });\n", | |
"\n", | |
" canvas_div.append(canvas);\n", | |
" canvas_div.append(rubberband);\n", | |
"\n", | |
" this.rubberband = rubberband;\n", | |
" this.rubberband_canvas = rubberband[0];\n", | |
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n", | |
" this.rubberband_context.strokeStyle = \"#000000\";\n", | |
"\n", | |
" this._resize_canvas = function(width, height) {\n", | |
" // Keep the size of the canvas, canvas container, and rubber band\n", | |
" // canvas in synch.\n", | |
" canvas_div.css('width', width)\n", | |
" canvas_div.css('height', height)\n", | |
"\n", | |
" canvas.attr('width', width);\n", | |
" canvas.attr('height', height);\n", | |
"\n", | |
" rubberband.attr('width', width);\n", | |
" rubberband.attr('height', height);\n", | |
" }\n", | |
"\n", | |
" // Set the figure to an initial 600x600px, this will subsequently be updated\n", | |
" // upon first draw.\n", | |
" this._resize_canvas(600, 600);\n", | |
"\n", | |
" // Disable right mouse context menu.\n", | |
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", | |
" return false;\n", | |
" });\n", | |
"\n", | |
" function set_focus () {\n", | |
" canvas.focus();\n", | |
" canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" window.setTimeout(set_focus, 100);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items) {\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) {\n", | |
" // put a spacer in here.\n", | |
" continue;\n", | |
" }\n", | |
" var button = $('<button/>');\n", | |
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", | |
" 'ui-button-icon-only');\n", | |
" button.attr('role', 'button');\n", | |
" button.attr('aria-disabled', 'false');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
"\n", | |
" var icon_img = $('<span/>');\n", | |
" icon_img.addClass('ui-button-icon-primary ui-icon');\n", | |
" icon_img.addClass(image);\n", | |
" icon_img.addClass('ui-corner-all');\n", | |
"\n", | |
" var tooltip_span = $('<span/>');\n", | |
" tooltip_span.addClass('ui-button-text');\n", | |
" tooltip_span.html(tooltip);\n", | |
"\n", | |
" button.append(icon_img);\n", | |
" button.append(tooltip_span);\n", | |
"\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" var fmt_picker_span = $('<span/>');\n", | |
"\n", | |
" var fmt_picker = $('<select/>');\n", | |
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", | |
" fmt_picker_span.append(fmt_picker);\n", | |
" nav_element.append(fmt_picker_span);\n", | |
" this.format_dropdown = fmt_picker[0];\n", | |
"\n", | |
" for (var ind in mpl.extensions) {\n", | |
" var fmt = mpl.extensions[ind];\n", | |
" var option = $(\n", | |
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", | |
" fmt_picker.append(option)\n", | |
" }\n", | |
"\n", | |
" // Add hover states to the ui-buttons\n", | |
" $( \".ui-button\" ).hover(\n", | |
" function() { $(this).addClass(\"ui-state-hover\");},\n", | |
" function() { $(this).removeClass(\"ui-state-hover\");}\n", | |
" );\n", | |
"\n", | |
" var status_bar = $('<span class=\"mpl-message\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", | |
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", | |
" // which will in turn request a refresh of the image.\n", | |
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_message = function(type, properties) {\n", | |
" properties['type'] = type;\n", | |
" properties['figure_id'] = this.id;\n", | |
" this.ws.send(JSON.stringify(properties));\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_draw_message = function() {\n", | |
" if (!this.waiting) {\n", | |
" this.waiting = true;\n", | |
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" var format_dropdown = fig.format_dropdown;\n", | |
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", | |
" fig.ondownload(fig, format);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n", | |
" var size = msg['size'];\n", | |
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", | |
" fig._resize_canvas(size[0], size[1]);\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", | |
" var x0 = msg['x0'];\n", | |
" var y0 = fig.canvas.height - msg['y0'];\n", | |
" var x1 = msg['x1'];\n", | |
" var y1 = fig.canvas.height - msg['y1'];\n", | |
" x0 = Math.floor(x0) + 0.5;\n", | |
" y0 = Math.floor(y0) + 0.5;\n", | |
" x1 = Math.floor(x1) + 0.5;\n", | |
" y1 = Math.floor(y1) + 0.5;\n", | |
" var min_x = Math.min(x0, x1);\n", | |
" var min_y = Math.min(y0, y1);\n", | |
" var width = Math.abs(x1 - x0);\n", | |
" var height = Math.abs(y1 - y0);\n", | |
"\n", | |
" fig.rubberband_context.clearRect(\n", | |
" 0, 0, fig.canvas.width, fig.canvas.height);\n", | |
"\n", | |
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n", | |
" // Updates the figure title.\n", | |
" fig.header.textContent = msg['label'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n", | |
" var cursor = msg['cursor'];\n", | |
" switch(cursor)\n", | |
" {\n", | |
" case 0:\n", | |
" cursor = 'pointer';\n", | |
" break;\n", | |
" case 1:\n", | |
" cursor = 'default';\n", | |
" break;\n", | |
" case 2:\n", | |
" cursor = 'crosshair';\n", | |
" break;\n", | |
" case 3:\n", | |
" cursor = 'move';\n", | |
" break;\n", | |
" }\n", | |
" fig.rubberband_canvas.style.cursor = cursor;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_message = function(fig, msg) {\n", | |
" fig.message.textContent = msg['message'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n", | |
" // Request the server to send over a new figure.\n", | |
" fig.send_draw_message();\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n", | |
" fig.image_mode = msg['mode'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Called whenever the canvas gets updated.\n", | |
" this.send_message(\"ack\", {});\n", | |
"}\n", | |
"\n", | |
"// A function to construct a web socket function for onmessage handling.\n", | |
"// Called in the figure constructor.\n", | |
"mpl.figure.prototype._make_on_message_function = function(fig) {\n", | |
" return function socket_on_message(evt) {\n", | |
" if (evt.data instanceof Blob) {\n", | |
" /* FIXME: We get \"Resource interpreted as Image but\n", | |
" * transferred with MIME type text/plain:\" errors on\n", | |
" * Chrome. But how to set the MIME type? It doesn't seem\n", | |
" * to be part of the websocket stream */\n", | |
" evt.data.type = \"image/png\";\n", | |
"\n", | |
" /* Free the memory for the previous frames */\n", | |
" if (fig.imageObj.src) {\n", | |
" (window.URL || window.webkitURL).revokeObjectURL(\n", | |
" fig.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", | |
" evt.data);\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n", | |
" fig.imageObj.src = evt.data;\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var msg = JSON.parse(evt.data);\n", | |
" var msg_type = msg['type'];\n", | |
"\n", | |
" // Call the \"handle_{type}\" callback, which takes\n", | |
" // the figure and JSON message as its only arguments.\n", | |
" try {\n", | |
" var callback = fig[\"handle_\" + msg_type];\n", | |
" } catch (e) {\n", | |
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" if (callback) {\n", | |
" try {\n", | |
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", | |
" callback(fig, msg);\n", | |
" } catch (e) {\n", | |
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n", | |
" }\n", | |
" }\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", | |
"mpl.findpos = function(e) {\n", | |
" //this section is from http://www.quirksmode.org/js/events_properties.html\n", | |
" var targ;\n", | |
" if (!e)\n", | |
" e = window.event;\n", | |
" if (e.target)\n", | |
" targ = e.target;\n", | |
" else if (e.srcElement)\n", | |
" targ = e.srcElement;\n", | |
" if (targ.nodeType == 3) // defeat Safari bug\n", | |
" targ = targ.parentNode;\n", | |
"\n", | |
" // jQuery normalizes the pageX and pageY\n", | |
" // pageX,Y are the mouse positions relative to the document\n", | |
" // offset() returns the position of the element relative to the document\n", | |
" var x = e.pageX - $(targ).offset().left;\n", | |
" var y = e.pageY - $(targ).offset().top;\n", | |
"\n", | |
" return {\"x\": x, \"y\": y};\n", | |
"};\n", | |
"\n", | |
"/*\n", | |
" * return a copy of an object with only non-object keys\n", | |
" * we need this to avoid circular references\n", | |
" * http://stackoverflow.com/a/24161582/3208463\n", | |
" */\n", | |
"function simpleKeys (original) {\n", | |
" return Object.keys(original).reduce(function (obj, key) {\n", | |
" if (typeof original[key] !== 'object')\n", | |
" obj[key] = original[key]\n", | |
" return obj;\n", | |
" }, {});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.mouse_event = function(event, name) {\n", | |
" var canvas_pos = mpl.findpos(event)\n", | |
"\n", | |
" if (name === 'button_press')\n", | |
" {\n", | |
" this.canvas.focus();\n", | |
" this.canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" var x = canvas_pos.x;\n", | |
" var y = canvas_pos.y;\n", | |
"\n", | |
" this.send_message(name, {x: x, y: y, button: event.button,\n", | |
" step: event.step,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
"\n", | |
" /* This prevents the web browser from automatically changing to\n", | |
" * the text insertion cursor when the button is pressed. We want\n", | |
" * to control all of the cursor setting manually through the\n", | |
" * 'cursor' event from matplotlib */\n", | |
" event.preventDefault();\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" // Handle any extra behaviour associated with a key event\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.key_event = function(event, name) {\n", | |
"\n", | |
" // Prevent repeat events\n", | |
" if (name == 'key_press')\n", | |
" {\n", | |
" if (event.which === this._key)\n", | |
" return;\n", | |
" else\n", | |
" this._key = event.which;\n", | |
" }\n", | |
" if (name == 'key_release')\n", | |
" this._key = null;\n", | |
"\n", | |
" var value = '';\n", | |
" if (event.ctrlKey && event.which != 17)\n", | |
" value += \"ctrl+\";\n", | |
" if (event.altKey && event.which != 18)\n", | |
" value += \"alt+\";\n", | |
" if (event.shiftKey && event.which != 16)\n", | |
" value += \"shift+\";\n", | |
"\n", | |
" value += 'k';\n", | |
" value += event.which.toString();\n", | |
"\n", | |
" this._key_event_extra(event, name);\n", | |
"\n", | |
" this.send_message(name, {key: value,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", | |
" if (name == 'download') {\n", | |
" this.handle_save(this, null);\n", | |
" } else {\n", | |
" this.send_message(\"toolbar_button\", {name: name});\n", | |
" }\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", | |
" this.message.textContent = tooltip;\n", | |
"};\n", | |
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", | |
"\n", | |
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", | |
"\n", | |
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", | |
" // Create a \"websocket\"-like object which calls the given IPython comm\n", | |
" // object with the appropriate methods. Currently this is a non binary\n", | |
" // socket, so there is still some room for performance tuning.\n", | |
" var ws = {};\n", | |
"\n", | |
" ws.close = function() {\n", | |
" comm.close()\n", | |
" };\n", | |
" ws.send = function(m) {\n", | |
" //console.log('sending', m);\n", | |
" comm.send(m);\n", | |
" };\n", | |
" // Register the callback with on_msg.\n", | |
" comm.on_msg(function(msg) {\n", | |
" //console.log('receiving', msg['content']['data'], msg);\n", | |
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", | |
" ws.onmessage(msg['content']['data'])\n", | |
" });\n", | |
" return ws;\n", | |
"}\n", | |
"\n", | |
"mpl.mpl_figure_comm = function(comm, msg) {\n", | |
" // This is the function which gets called when the mpl process\n", | |
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", | |
"\n", | |
" var id = msg.content.data.id;\n", | |
" // Get hold of the div created by the display call when the Comm\n", | |
" // socket was opened in Python.\n", | |
" var element = $(\"#\" + id);\n", | |
" var ws_proxy = comm_websocket_adapter(comm)\n", | |
"\n", | |
" function ondownload(figure, format) {\n", | |
" window.open(figure.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" var fig = new mpl.figure(id, ws_proxy,\n", | |
" ondownload,\n", | |
" element.get(0));\n", | |
"\n", | |
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", | |
" // web socket which is closed, not our websocket->open comm proxy.\n", | |
" ws_proxy.onopen();\n", | |
"\n", | |
" fig.parent_element = element.get(0);\n", | |
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", | |
" if (!fig.cell_info) {\n", | |
" console.error(\"Failed to find cell for figure\", id, fig);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var output_index = fig.cell_info[2]\n", | |
" var cell = fig.cell_info[0];\n", | |
"\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", | |
" fig.root.unbind('remove')\n", | |
"\n", | |
" // Update the output cell to use the data from the current canvas.\n", | |
" fig.push_to_output();\n", | |
" var dataURL = fig.canvas.toDataURL();\n", | |
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n", | |
" // the notebook keyboard shortcuts fail.\n", | |
" IPython.keyboard_manager.enable()\n", | |
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n", | |
" fig.close_ws(fig, msg);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.close_ws = function(fig, msg){\n", | |
" fig.send_message('closing', msg);\n", | |
" // fig.ws.close()\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n", | |
" // Turn the data on the canvas into data in the output cell.\n", | |
" var dataURL = this.canvas.toDataURL();\n", | |
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Tell IPython that the notebook contents must change.\n", | |
" IPython.notebook.set_dirty(true);\n", | |
" this.send_message(\"ack\", {});\n", | |
" var fig = this;\n", | |
" // Wait a second, then push the new image to the DOM so\n", | |
" // that it is saved nicely (might be nice to debounce this).\n", | |
" setTimeout(function () { fig.push_to_output() }, 1000);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items){\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) { continue; };\n", | |
"\n", | |
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" // Add the status bar.\n", | |
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"\n", | |
" // Add the close button to the window.\n", | |
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n", | |
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n", | |
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", | |
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n", | |
" buttongrp.append(button);\n", | |
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", | |
" titlebar.prepend(buttongrp);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(el){\n", | |
" var fig = this\n", | |
" el.on(\"remove\", function(){\n", | |
"\tfig.close_ws(fig, {});\n", | |
" });\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(el){\n", | |
" // this is important to make the div 'focusable\n", | |
" el.attr('tabindex', 0)\n", | |
" // reach out to IPython and tell the keyboard manager to turn it's self\n", | |
" // off when our div gets focus\n", | |
"\n", | |
" // location in version 3\n", | |
" if (IPython.notebook.keyboard_manager) {\n", | |
" IPython.notebook.keyboard_manager.register_events(el);\n", | |
" }\n", | |
" else {\n", | |
" // location in version 2\n", | |
" IPython.keyboard_manager.register_events(el);\n", | |
" }\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" var manager = IPython.notebook.keyboard_manager;\n", | |
" if (!manager)\n", | |
" manager = IPython.keyboard_manager;\n", | |
"\n", | |
" // Check for shift+enter\n", | |
" if (event.shiftKey && event.which == 13) {\n", | |
" this.canvas_div.blur();\n", | |
" // select the cell after this one\n", | |
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", | |
" IPython.notebook.select(index + 1);\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" fig.ondownload(fig, null);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.find_output_cell = function(html_output) {\n", | |
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", | |
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", | |
" // IPython event is triggered only after the cells have been serialised, which for\n", | |
" // our purposes (turning an active figure into a static one), is too late.\n", | |
" var cells = IPython.notebook.get_cells();\n", | |
" var ncells = cells.length;\n", | |
" for (var i=0; i<ncells; i++) {\n", | |
" var cell = cells[i];\n", | |
" if (cell.cell_type === 'code'){\n", | |
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", | |
" var data = cell.output_area.outputs[j];\n", | |
" if (data.data) {\n", | |
" // IPython >= 3 moved mimebundle to data attribute of output\n", | |
" data = data.data;\n", | |
" }\n", | |
" if (data['text/html'] == html_output) {\n", | |
" return [cell, data, j];\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"// Register the function which deals with the matplotlib target/channel.\n", | |
"// The kernel may be null if the page has been refreshed.\n", | |
"if (IPython.notebook.kernel != null) {\n", | |
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", | |
"}\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"<img src=\"data:image/png;base64,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\">" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"plotResults(pcaDF, mainChars)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Latent Semantic Analysis\n", | |
"\n", | |
"See http://scikit-learn.org/stable/modules/decomposition.html#truncated-singular-value-decomposition-and-latent-semantic-analysis" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 38, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# First, redo vectors using tfidf\n", | |
"tv = TfidfVectorizer()\n", | |
"out = tv.fit_transform(characters).todense()\n", | |
"\n", | |
"df = pd.DataFrame(out)\n", | |
"\n", | |
"tsvd = TruncatedSVD(n_components=3)\n", | |
"lsaed = tsvd.fit_transform(df)\n", | |
"lsaDF = pd.DataFrame(lsaed)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/javascript": [ | |
"/* Put everything inside the global mpl namespace */\n", | |
"window.mpl = {};\n", | |
"\n", | |
"mpl.get_websocket_type = function() {\n", | |
" if (typeof(WebSocket) !== 'undefined') {\n", | |
" return WebSocket;\n", | |
" } else if (typeof(MozWebSocket) !== 'undefined') {\n", | |
" return MozWebSocket;\n", | |
" } else {\n", | |
" alert('Your browser does not have WebSocket support.' +\n", | |
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", | |
" 'Firefox 4 and 5 are also supported but you ' +\n", | |
" 'have to enable WebSockets in about:config.');\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", | |
" this.id = figure_id;\n", | |
"\n", | |
" this.ws = websocket;\n", | |
"\n", | |
" this.supports_binary = (this.ws.binaryType != undefined);\n", | |
"\n", | |
" if (!this.supports_binary) {\n", | |
" var warnings = document.getElementById(\"mpl-warnings\");\n", | |
" if (warnings) {\n", | |
" warnings.style.display = 'block';\n", | |
" warnings.textContent = (\n", | |
" \"This browser does not support binary websocket messages. \" +\n", | |
" \"Performance may be slow.\");\n", | |
" }\n", | |
" }\n", | |
"\n", | |
" this.imageObj = new Image();\n", | |
"\n", | |
" this.context = undefined;\n", | |
" this.message = undefined;\n", | |
" this.canvas = undefined;\n", | |
" this.rubberband_canvas = undefined;\n", | |
" this.rubberband_context = undefined;\n", | |
" this.format_dropdown = undefined;\n", | |
"\n", | |
" this.image_mode = 'full';\n", | |
"\n", | |
" this.root = $('<div/>');\n", | |
" this._root_extra_style(this.root)\n", | |
" this.root.attr('style', 'display: inline-block');\n", | |
"\n", | |
" $(parent_element).append(this.root);\n", | |
"\n", | |
" this._init_header(this);\n", | |
" this._init_canvas(this);\n", | |
" this._init_toolbar(this);\n", | |
"\n", | |
" var fig = this;\n", | |
"\n", | |
" this.waiting = false;\n", | |
"\n", | |
" this.ws.onopen = function () {\n", | |
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", | |
" fig.send_message(\"send_image_mode\", {});\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" }\n", | |
"\n", | |
" this.imageObj.onload = function() {\n", | |
" if (fig.image_mode == 'full') {\n", | |
" // Full images could contain transparency (where diff images\n", | |
" // almost always do), so we need to clear the canvas so that\n", | |
" // there is no ghosting.\n", | |
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", | |
" }\n", | |
" fig.context.drawImage(fig.imageObj, 0, 0);\n", | |
" };\n", | |
"\n", | |
" this.imageObj.onunload = function() {\n", | |
" this.ws.close();\n", | |
" }\n", | |
"\n", | |
" this.ws.onmessage = this._make_on_message_function(this);\n", | |
"\n", | |
" this.ondownload = ondownload;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_header = function() {\n", | |
" var titlebar = $(\n", | |
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n", | |
" 'ui-helper-clearfix\"/>');\n", | |
" var titletext = $(\n", | |
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n", | |
" 'text-align: center; padding: 3px;\"/>');\n", | |
" titlebar.append(titletext)\n", | |
" this.root.append(titlebar);\n", | |
" this.header = titletext[0];\n", | |
"}\n", | |
"\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_canvas = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var canvas_div = $('<div/>');\n", | |
"\n", | |
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", | |
"\n", | |
" function canvas_keyboard_event(event) {\n", | |
" return fig.key_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" canvas_div.keydown('key_press', canvas_keyboard_event);\n", | |
" canvas_div.keyup('key_release', canvas_keyboard_event);\n", | |
" this.canvas_div = canvas_div\n", | |
" this._canvas_extra_style(canvas_div)\n", | |
" this.root.append(canvas_div);\n", | |
"\n", | |
" var canvas = $('<canvas/>');\n", | |
" canvas.addClass('mpl-canvas');\n", | |
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", | |
"\n", | |
" this.canvas = canvas[0];\n", | |
" this.context = canvas[0].getContext(\"2d\");\n", | |
"\n", | |
" var rubberband = $('<canvas/>');\n", | |
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", | |
"\n", | |
" var pass_mouse_events = true;\n", | |
"\n", | |
" canvas_div.resizable({\n", | |
" start: function(event, ui) {\n", | |
" pass_mouse_events = false;\n", | |
" },\n", | |
" resize: function(event, ui) {\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" stop: function(event, ui) {\n", | |
" pass_mouse_events = true;\n", | |
" fig.request_resize(ui.size.width, ui.size.height);\n", | |
" },\n", | |
" });\n", | |
"\n", | |
" function mouse_event_fn(event) {\n", | |
" if (pass_mouse_events)\n", | |
" return fig.mouse_event(event, event['data']);\n", | |
" }\n", | |
"\n", | |
" rubberband.mousedown('button_press', mouse_event_fn);\n", | |
" rubberband.mouseup('button_release', mouse_event_fn);\n", | |
" // Throttle sequential mouse events to 1 every 20ms.\n", | |
" rubberband.mousemove('motion_notify', mouse_event_fn);\n", | |
"\n", | |
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n", | |
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n", | |
"\n", | |
" canvas_div.on(\"wheel\", function (event) {\n", | |
" event = event.originalEvent;\n", | |
" event['data'] = 'scroll'\n", | |
" if (event.deltaY < 0) {\n", | |
" event.step = 1;\n", | |
" } else {\n", | |
" event.step = -1;\n", | |
" }\n", | |
" mouse_event_fn(event);\n", | |
" });\n", | |
"\n", | |
" canvas_div.append(canvas);\n", | |
" canvas_div.append(rubberband);\n", | |
"\n", | |
" this.rubberband = rubberband;\n", | |
" this.rubberband_canvas = rubberband[0];\n", | |
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n", | |
" this.rubberband_context.strokeStyle = \"#000000\";\n", | |
"\n", | |
" this._resize_canvas = function(width, height) {\n", | |
" // Keep the size of the canvas, canvas container, and rubber band\n", | |
" // canvas in synch.\n", | |
" canvas_div.css('width', width)\n", | |
" canvas_div.css('height', height)\n", | |
"\n", | |
" canvas.attr('width', width);\n", | |
" canvas.attr('height', height);\n", | |
"\n", | |
" rubberband.attr('width', width);\n", | |
" rubberband.attr('height', height);\n", | |
" }\n", | |
"\n", | |
" // Set the figure to an initial 600x600px, this will subsequently be updated\n", | |
" // upon first draw.\n", | |
" this._resize_canvas(600, 600);\n", | |
"\n", | |
" // Disable right mouse context menu.\n", | |
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", | |
" return false;\n", | |
" });\n", | |
"\n", | |
" function set_focus () {\n", | |
" canvas.focus();\n", | |
" canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" window.setTimeout(set_focus, 100);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items) {\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) {\n", | |
" // put a spacer in here.\n", | |
" continue;\n", | |
" }\n", | |
" var button = $('<button/>');\n", | |
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n", | |
" 'ui-button-icon-only');\n", | |
" button.attr('role', 'button');\n", | |
" button.attr('aria-disabled', 'false');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
"\n", | |
" var icon_img = $('<span/>');\n", | |
" icon_img.addClass('ui-button-icon-primary ui-icon');\n", | |
" icon_img.addClass(image);\n", | |
" icon_img.addClass('ui-corner-all');\n", | |
"\n", | |
" var tooltip_span = $('<span/>');\n", | |
" tooltip_span.addClass('ui-button-text');\n", | |
" tooltip_span.html(tooltip);\n", | |
"\n", | |
" button.append(icon_img);\n", | |
" button.append(tooltip_span);\n", | |
"\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" var fmt_picker_span = $('<span/>');\n", | |
"\n", | |
" var fmt_picker = $('<select/>');\n", | |
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n", | |
" fmt_picker_span.append(fmt_picker);\n", | |
" nav_element.append(fmt_picker_span);\n", | |
" this.format_dropdown = fmt_picker[0];\n", | |
"\n", | |
" for (var ind in mpl.extensions) {\n", | |
" var fmt = mpl.extensions[ind];\n", | |
" var option = $(\n", | |
" '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n", | |
" fmt_picker.append(option)\n", | |
" }\n", | |
"\n", | |
" // Add hover states to the ui-buttons\n", | |
" $( \".ui-button\" ).hover(\n", | |
" function() { $(this).addClass(\"ui-state-hover\");},\n", | |
" function() { $(this).removeClass(\"ui-state-hover\");}\n", | |
" );\n", | |
"\n", | |
" var status_bar = $('<span class=\"mpl-message\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n", | |
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", | |
" // which will in turn request a refresh of the image.\n", | |
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_message = function(type, properties) {\n", | |
" properties['type'] = type;\n", | |
" properties['figure_id'] = this.id;\n", | |
" this.ws.send(JSON.stringify(properties));\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.send_draw_message = function() {\n", | |
" if (!this.waiting) {\n", | |
" this.waiting = true;\n", | |
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" var format_dropdown = fig.format_dropdown;\n", | |
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", | |
" fig.ondownload(fig, format);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n", | |
" var size = msg['size'];\n", | |
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n", | |
" fig._resize_canvas(size[0], size[1]);\n", | |
" fig.send_message(\"refresh\", {});\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n", | |
" var x0 = msg['x0'];\n", | |
" var y0 = fig.canvas.height - msg['y0'];\n", | |
" var x1 = msg['x1'];\n", | |
" var y1 = fig.canvas.height - msg['y1'];\n", | |
" x0 = Math.floor(x0) + 0.5;\n", | |
" y0 = Math.floor(y0) + 0.5;\n", | |
" x1 = Math.floor(x1) + 0.5;\n", | |
" y1 = Math.floor(y1) + 0.5;\n", | |
" var min_x = Math.min(x0, x1);\n", | |
" var min_y = Math.min(y0, y1);\n", | |
" var width = Math.abs(x1 - x0);\n", | |
" var height = Math.abs(y1 - y0);\n", | |
"\n", | |
" fig.rubberband_context.clearRect(\n", | |
" 0, 0, fig.canvas.width, fig.canvas.height);\n", | |
"\n", | |
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n", | |
" // Updates the figure title.\n", | |
" fig.header.textContent = msg['label'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n", | |
" var cursor = msg['cursor'];\n", | |
" switch(cursor)\n", | |
" {\n", | |
" case 0:\n", | |
" cursor = 'pointer';\n", | |
" break;\n", | |
" case 1:\n", | |
" cursor = 'default';\n", | |
" break;\n", | |
" case 2:\n", | |
" cursor = 'crosshair';\n", | |
" break;\n", | |
" case 3:\n", | |
" cursor = 'move';\n", | |
" break;\n", | |
" }\n", | |
" fig.rubberband_canvas.style.cursor = cursor;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_message = function(fig, msg) {\n", | |
" fig.message.textContent = msg['message'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n", | |
" // Request the server to send over a new figure.\n", | |
" fig.send_draw_message();\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n", | |
" fig.image_mode = msg['mode'];\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Called whenever the canvas gets updated.\n", | |
" this.send_message(\"ack\", {});\n", | |
"}\n", | |
"\n", | |
"// A function to construct a web socket function for onmessage handling.\n", | |
"// Called in the figure constructor.\n", | |
"mpl.figure.prototype._make_on_message_function = function(fig) {\n", | |
" return function socket_on_message(evt) {\n", | |
" if (evt.data instanceof Blob) {\n", | |
" /* FIXME: We get \"Resource interpreted as Image but\n", | |
" * transferred with MIME type text/plain:\" errors on\n", | |
" * Chrome. But how to set the MIME type? It doesn't seem\n", | |
" * to be part of the websocket stream */\n", | |
" evt.data.type = \"image/png\";\n", | |
"\n", | |
" /* Free the memory for the previous frames */\n", | |
" if (fig.imageObj.src) {\n", | |
" (window.URL || window.webkitURL).revokeObjectURL(\n", | |
" fig.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", | |
" evt.data);\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n", | |
" fig.imageObj.src = evt.data;\n", | |
" fig.updated_canvas_event();\n", | |
" fig.waiting = false;\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var msg = JSON.parse(evt.data);\n", | |
" var msg_type = msg['type'];\n", | |
"\n", | |
" // Call the \"handle_{type}\" callback, which takes\n", | |
" // the figure and JSON message as its only arguments.\n", | |
" try {\n", | |
" var callback = fig[\"handle_\" + msg_type];\n", | |
" } catch (e) {\n", | |
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" if (callback) {\n", | |
" try {\n", | |
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", | |
" callback(fig, msg);\n", | |
" } catch (e) {\n", | |
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n", | |
" }\n", | |
" }\n", | |
" };\n", | |
"}\n", | |
"\n", | |
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", | |
"mpl.findpos = function(e) {\n", | |
" //this section is from http://www.quirksmode.org/js/events_properties.html\n", | |
" var targ;\n", | |
" if (!e)\n", | |
" e = window.event;\n", | |
" if (e.target)\n", | |
" targ = e.target;\n", | |
" else if (e.srcElement)\n", | |
" targ = e.srcElement;\n", | |
" if (targ.nodeType == 3) // defeat Safari bug\n", | |
" targ = targ.parentNode;\n", | |
"\n", | |
" // jQuery normalizes the pageX and pageY\n", | |
" // pageX,Y are the mouse positions relative to the document\n", | |
" // offset() returns the position of the element relative to the document\n", | |
" var x = e.pageX - $(targ).offset().left;\n", | |
" var y = e.pageY - $(targ).offset().top;\n", | |
"\n", | |
" return {\"x\": x, \"y\": y};\n", | |
"};\n", | |
"\n", | |
"/*\n", | |
" * return a copy of an object with only non-object keys\n", | |
" * we need this to avoid circular references\n", | |
" * http://stackoverflow.com/a/24161582/3208463\n", | |
" */\n", | |
"function simpleKeys (original) {\n", | |
" return Object.keys(original).reduce(function (obj, key) {\n", | |
" if (typeof original[key] !== 'object')\n", | |
" obj[key] = original[key]\n", | |
" return obj;\n", | |
" }, {});\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.mouse_event = function(event, name) {\n", | |
" var canvas_pos = mpl.findpos(event)\n", | |
"\n", | |
" if (name === 'button_press')\n", | |
" {\n", | |
" this.canvas.focus();\n", | |
" this.canvas_div.focus();\n", | |
" }\n", | |
"\n", | |
" var x = canvas_pos.x;\n", | |
" var y = canvas_pos.y;\n", | |
"\n", | |
" this.send_message(name, {x: x, y: y, button: event.button,\n", | |
" step: event.step,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
"\n", | |
" /* This prevents the web browser from automatically changing to\n", | |
" * the text insertion cursor when the button is pressed. We want\n", | |
" * to control all of the cursor setting manually through the\n", | |
" * 'cursor' event from matplotlib */\n", | |
" event.preventDefault();\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" // Handle any extra behaviour associated with a key event\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.key_event = function(event, name) {\n", | |
"\n", | |
" // Prevent repeat events\n", | |
" if (name == 'key_press')\n", | |
" {\n", | |
" if (event.which === this._key)\n", | |
" return;\n", | |
" else\n", | |
" this._key = event.which;\n", | |
" }\n", | |
" if (name == 'key_release')\n", | |
" this._key = null;\n", | |
"\n", | |
" var value = '';\n", | |
" if (event.ctrlKey && event.which != 17)\n", | |
" value += \"ctrl+\";\n", | |
" if (event.altKey && event.which != 18)\n", | |
" value += \"alt+\";\n", | |
" if (event.shiftKey && event.which != 16)\n", | |
" value += \"shift+\";\n", | |
"\n", | |
" value += 'k';\n", | |
" value += event.which.toString();\n", | |
"\n", | |
" this._key_event_extra(event, name);\n", | |
"\n", | |
" this.send_message(name, {key: value,\n", | |
" guiEvent: simpleKeys(event)});\n", | |
" return false;\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", | |
" if (name == 'download') {\n", | |
" this.handle_save(this, null);\n", | |
" } else {\n", | |
" this.send_message(\"toolbar_button\", {name: name});\n", | |
" }\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", | |
" this.message.textContent = tooltip;\n", | |
"};\n", | |
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", | |
"\n", | |
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n", | |
"\n", | |
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", | |
" // Create a \"websocket\"-like object which calls the given IPython comm\n", | |
" // object with the appropriate methods. Currently this is a non binary\n", | |
" // socket, so there is still some room for performance tuning.\n", | |
" var ws = {};\n", | |
"\n", | |
" ws.close = function() {\n", | |
" comm.close()\n", | |
" };\n", | |
" ws.send = function(m) {\n", | |
" //console.log('sending', m);\n", | |
" comm.send(m);\n", | |
" };\n", | |
" // Register the callback with on_msg.\n", | |
" comm.on_msg(function(msg) {\n", | |
" //console.log('receiving', msg['content']['data'], msg);\n", | |
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", | |
" ws.onmessage(msg['content']['data'])\n", | |
" });\n", | |
" return ws;\n", | |
"}\n", | |
"\n", | |
"mpl.mpl_figure_comm = function(comm, msg) {\n", | |
" // This is the function which gets called when the mpl process\n", | |
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", | |
"\n", | |
" var id = msg.content.data.id;\n", | |
" // Get hold of the div created by the display call when the Comm\n", | |
" // socket was opened in Python.\n", | |
" var element = $(\"#\" + id);\n", | |
" var ws_proxy = comm_websocket_adapter(comm)\n", | |
"\n", | |
" function ondownload(figure, format) {\n", | |
" window.open(figure.imageObj.src);\n", | |
" }\n", | |
"\n", | |
" var fig = new mpl.figure(id, ws_proxy,\n", | |
" ondownload,\n", | |
" element.get(0));\n", | |
"\n", | |
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", | |
" // web socket which is closed, not our websocket->open comm proxy.\n", | |
" ws_proxy.onopen();\n", | |
"\n", | |
" fig.parent_element = element.get(0);\n", | |
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", | |
" if (!fig.cell_info) {\n", | |
" console.error(\"Failed to find cell for figure\", id, fig);\n", | |
" return;\n", | |
" }\n", | |
"\n", | |
" var output_index = fig.cell_info[2]\n", | |
" var cell = fig.cell_info[0];\n", | |
"\n", | |
"};\n", | |
"\n", | |
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", | |
" fig.root.unbind('remove')\n", | |
"\n", | |
" // Update the output cell to use the data from the current canvas.\n", | |
" fig.push_to_output();\n", | |
" var dataURL = fig.canvas.toDataURL();\n", | |
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n", | |
" // the notebook keyboard shortcuts fail.\n", | |
" IPython.keyboard_manager.enable()\n", | |
" $(fig.parent_element).html('<img src=\"' + dataURL + '\">');\n", | |
" fig.close_ws(fig, msg);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.close_ws = function(fig, msg){\n", | |
" fig.send_message('closing', msg);\n", | |
" // fig.ws.close()\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n", | |
" // Turn the data on the canvas into data in the output cell.\n", | |
" var dataURL = this.canvas.toDataURL();\n", | |
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.updated_canvas_event = function() {\n", | |
" // Tell IPython that the notebook contents must change.\n", | |
" IPython.notebook.set_dirty(true);\n", | |
" this.send_message(\"ack\", {});\n", | |
" var fig = this;\n", | |
" // Wait a second, then push the new image to the DOM so\n", | |
" // that it is saved nicely (might be nice to debounce this).\n", | |
" setTimeout(function () { fig.push_to_output() }, 1000);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._init_toolbar = function() {\n", | |
" var fig = this;\n", | |
"\n", | |
" var nav_element = $('<div/>')\n", | |
" nav_element.attr('style', 'width: 100%');\n", | |
" this.root.append(nav_element);\n", | |
"\n", | |
" // Define a callback function for later on.\n", | |
" function toolbar_event(event) {\n", | |
" return fig.toolbar_button_onclick(event['data']);\n", | |
" }\n", | |
" function toolbar_mouse_event(event) {\n", | |
" return fig.toolbar_button_onmouseover(event['data']);\n", | |
" }\n", | |
"\n", | |
" for(var toolbar_ind in mpl.toolbar_items){\n", | |
" var name = mpl.toolbar_items[toolbar_ind][0];\n", | |
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", | |
" var image = mpl.toolbar_items[toolbar_ind][2];\n", | |
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n", | |
"\n", | |
" if (!name) { continue; };\n", | |
"\n", | |
" var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n", | |
" button.click(method_name, toolbar_event);\n", | |
" button.mouseover(tooltip, toolbar_mouse_event);\n", | |
" nav_element.append(button);\n", | |
" }\n", | |
"\n", | |
" // Add the status bar.\n", | |
" var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n", | |
" nav_element.append(status_bar);\n", | |
" this.message = status_bar[0];\n", | |
"\n", | |
" // Add the close button to the window.\n", | |
" var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n", | |
" var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n", | |
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", | |
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n", | |
" buttongrp.append(button);\n", | |
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", | |
" titlebar.prepend(buttongrp);\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._root_extra_style = function(el){\n", | |
" var fig = this\n", | |
" el.on(\"remove\", function(){\n", | |
"\tfig.close_ws(fig, {});\n", | |
" });\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._canvas_extra_style = function(el){\n", | |
" // this is important to make the div 'focusable\n", | |
" el.attr('tabindex', 0)\n", | |
" // reach out to IPython and tell the keyboard manager to turn it's self\n", | |
" // off when our div gets focus\n", | |
"\n", | |
" // location in version 3\n", | |
" if (IPython.notebook.keyboard_manager) {\n", | |
" IPython.notebook.keyboard_manager.register_events(el);\n", | |
" }\n", | |
" else {\n", | |
" // location in version 2\n", | |
" IPython.keyboard_manager.register_events(el);\n", | |
" }\n", | |
"\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", | |
" var manager = IPython.notebook.keyboard_manager;\n", | |
" if (!manager)\n", | |
" manager = IPython.keyboard_manager;\n", | |
"\n", | |
" // Check for shift+enter\n", | |
" if (event.shiftKey && event.which == 13) {\n", | |
" this.canvas_div.blur();\n", | |
" // select the cell after this one\n", | |
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", | |
" IPython.notebook.select(index + 1);\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", | |
" fig.ondownload(fig, null);\n", | |
"}\n", | |
"\n", | |
"\n", | |
"mpl.find_output_cell = function(html_output) {\n", | |
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", | |
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", | |
" // IPython event is triggered only after the cells have been serialised, which for\n", | |
" // our purposes (turning an active figure into a static one), is too late.\n", | |
" var cells = IPython.notebook.get_cells();\n", | |
" var ncells = cells.length;\n", | |
" for (var i=0; i<ncells; i++) {\n", | |
" var cell = cells[i];\n", | |
" if (cell.cell_type === 'code'){\n", | |
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", | |
" var data = cell.output_area.outputs[j];\n", | |
" if (data.data) {\n", | |
" // IPython >= 3 moved mimebundle to data attribute of output\n", | |
" data = data.data;\n", | |
" }\n", | |
" if (data['text/html'] == html_output) {\n", | |
" return [cell, data, j];\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
"}\n", | |
"\n", | |
"// Register the function which deals with the matplotlib target/channel.\n", | |
"// The kernel may be null if the page has been refreshed.\n", | |
"if (IPython.notebook.kernel != null) {\n", | |
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", | |
"}\n" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"<img src=\"data:image/png;base64,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DAC4d+8eRo8ejapVqyIpKcl+N4Tcgty5iUgIwQBNrkPKBigDrVaLWrVqQa1Wu/xUuby8POzevRuffPIJwsPDERYWhtGjR2P79u3IyMiQFJQzMjJw5MgRLF68GB999BFatWoFjUaDpk2b4v3338e8efNw4MABZGVlMSgrgD1GWZtTu3ZtfP/99zY/f3IvcucmIiEEAzS5BikboIwNHDgQ7du3d4sAbUyv1yM5ORk///wzoqKi4Ofnh3bt2mHatGk4ceJEUblHTk4OLl++jLi4OEyaNAm9evVCvXr1EBwcjMjISEyYMAHr16/H1atX3er6uSJbj7I255VXXsGSJUtsd9LkluTOTURCCAZocg3lmZC4efNmNG7cGL///rvbBWhThYWFOHfuHKZPn44333wTL7/8MjQaDTQaDV5//XUMHToUixYtwpEjR5CTk8NVZRdk61HWGzduLCrXyMrKwtixY1G1alUkJiY69HaR65E7NxEJIRigSfnKswEqPT0dL730Ev7880/s27fP7QO0qXv37uHo0aO8Jm7GlqOs//d//xfPP/88vLy88Pzzz6Nz5844ffq0w28TuR65cxOREIIBmpSvPBugevXqhSlTpgAAAzQRkYLInZuIhBAM0KR8UlegV61ahUaNGhUF5r1790KtVqOgoMAh50tEROUnd24iEkIwQJNrkLIBKjo6Gt7e3nj22Wfx7LPPonLlykXT/VasWOHI0yYiIonkzk1EQggGaHINUjZAZWVl4c6dO0XH2rVroVarkZiYiLy8PBnOnoiIrCV3biISQjBAk+uQsgHKGGugSUoP8b/++gsdOnTAs88+i2eeeQYDBw5ETk5Ose/Zu3cvwsLC4OnpiVdeeQULFy60900gchty5yYiIQQDNBG5Nyk9xLVaLf71r3/hiy++QH5+PtLS0tCyZUtERkYWfc/Nmzfh5eWFhQsXIj8/H/v370flypWxceNGR94sIpcld24iEkIwQBORe5PSQ3zHjh3w9vYu9rXdu3fjsccew507dwAAX331FcLCwop9z8iRI9GmTRs7nD2R+5E7NxEJIRigiexN6ojxZcuWoV69evDy8kKNGjUwYsQIB52p+5HawWXbtm3w8vIqNkhm586dUKvV2Lp1KwCge/fuGDJkSLGfW7lyJZ555hk73AIi9yN3biISQjBAE9mT1BHjM2bMwCuvvILDhw+jsLAQeXl5HD5hR1J7iGdlZeG5555DTEwM7t+/j9u3b6NFixZQq9VYuXIlAKB169aIiYkp9nM7duzAE088Yb8bQuRG5M5NREIIBmgie5JSHqDVauHt7Y1t27Y58hTdWnmmWJ4+fRpt27ZF9erV4efnh8WLF0OlUuG3334DwBVoInuTOzcRCSEYoInsRWo4i4+Ph1qtxqJFi+Dn54caNWqgffv2OHv2rKNO2S1J6SFuzsaNG+Ht7Q2tVgvgUQ10eHh4se9hDTSR7cidm4iEEAzQRPYitTwgNjYWKpUKLVq0QHJyMh48eIBx48bh+eefLwpnZHtSeogDwMmTJ5Gbm4uCggIcOHAAtWvXxsyZM4v+3tCFY9GiRXj48CEOHDgAX19fduEgshG5cxOREIIBmshepK5Ab968GSqVCjt37iz6WmFhITw9PREfH2/383VnUnqIDx06FM888wy8vLxQt25d/PjjjyX+vf379yM0NBSenp6oXbs2Fi1a5LDbQuTq5M5NREIIBmgie5JSHmBYsTYO0AUFBQzQRERG5M5NREIIBmgie5JaHhAZGYmWLVsiNTW1qGvHiy++WGLSHRGRu5I7NxEJIRigiexNSnlATk4O3nvvPVSpUgXPPvssOnTogAsXLsh16kRETkfu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NREIIBmgiIiJSDrlzE5EQggGaiIiIlEPu3EQkhGCAJiIiIuWQOzcRCSEYoImIiEg55M5NRERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERCSL/wfwTySEhkSNPAAAAABJRU5ErkJggg==\">" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"plotResults(lsaDF, mainChars)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.5.2" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment