|
{ |
|
"cells": [ |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 1, |
|
"metadata": {}, |
|
"outputs": [ |
|
{ |
|
"name": "stderr", |
|
"output_type": "stream", |
|
"text": [ |
|
"/Users/guyer/anaconda/envs/parallel2/lib/python2.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated. You should import from ipykernel or jupyter_client instead.\n", |
|
" \"You should import from ipykernel or jupyter_client instead.\", ShimWarning)\n" |
|
] |
|
} |
|
], |
|
"source": [ |
|
"%matplotlib notebook" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 2, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"import fipy as fp" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 3, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"from fipy import numerix as nmx" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 4, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"dx = 1. # .5\n", |
|
"Lx = 200." |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 5, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"mesh = fp.Grid2D(dx=dx, Lx=Lx, dy=dx, Ly=Lx)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 6, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"u = fp.CellVariable(mesh=mesh, name=\"u\", hasOld=True)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 7, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"phi = fp.CellVariable(mesh=mesh, name=r\"$\\varphi$\", hasOld=True)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 8, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"r = nmx.sqrtDot(mesh.cellCenters, mesh.cellCenters)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 9, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"D = 10.\n", |
|
"tau0 = 1.\n", |
|
"W0 = 1.\n", |
|
"lamda = D * tau0 / (0.6267 * W0**2)\n", |
|
"theta = nmx.arctan2(phi.grad[1], phi.grad[0])\n", |
|
"theta.name = r\"$\\theta$\"\n", |
|
"theta_f = nmx.arctan2(phi.faceGrad[1], phi.faceGrad[0])\n", |
|
"theta_f.name = r\"$\\theta$\"\n", |
|
"n = fp.Variable(4)\n", |
|
"epsilon = fp.Variable(0.025)\n", |
|
"a = 1 + epsilon * nmx.cos(n * theta)\n", |
|
"a_f = 1 + epsilon * nmx.cos(n * theta_f)\n", |
|
"aprime_f = -epsilon * n * nmx.sin(n * theta_f)\n", |
|
"tau = tau0 * a**2\n", |
|
"W = W0 * a\n", |
|
"Delta = fp.Variable(value=0.3, name=r\"$\\Delta$\")" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 10, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"# u.constrain(-Delta, where=mesh.facesRight | mesh.facesTop)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 11, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"n.value = 4" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 12, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"ueq = (fp.TransientTerm(coeff=1., var=u) \n", |
|
" == fp.DiffusionTerm(coeff=D, var=u)\n", |
|
" + fp.TransientTerm(coeff=0.5, var=phi))" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 13, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"I0 = fp.Variable(value=((1,0), (0,1)))\n", |
|
"I1 = fp.Variable(value=((0,-1), (1,0)))\n", |
|
"Dphi = W0**2 * a_f * (a_f * I0 + aprime_f * I1)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 14, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"phieq = (fp.TransientTerm(coeff=tau, var=phi)\n", |
|
" == fp.DiffusionTerm(coeff=Dphi, var=phi)\n", |
|
" + fp.ImplicitSourceTerm(coeff=1-phi**2, var=phi)\n", |
|
" - fp.ImplicitSourceTerm(coeff=lamda * (1 - 2*phi**2 + phi**4), var=u))" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 15, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"eq = ueq & phieq" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 16, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"phi.value = -1\n", |
|
"phi.setValue(+1, where=r <= 8.)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 17, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"u.value = -Delta" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 18, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"faceNorm = phi.faceGrad / (phi.faceGrad.mag + (phi.faceGrad.mag == 0.) * 1.)\n", |
|
"faceNorm.name = r\"$\\hat{n}$\"\n", |
|
"curvature = faceNorm.divergence\n", |
|
"curvature.name = r\"$\\kappa$\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 19, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [ |
|
"radius = 1. / curvature\n", |
|
"radius.name = r\"$\\rho$\"" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 20, |
|
"metadata": { |
|
"scrolled": false |
|
}, |
|
"outputs": [ |
|
{ |
|
"data": { |
|
"application/javascript": [ |
|
"/* Put everything inside the global mpl namespace */\n", |
|
"window.mpl = {};\n", |
|
"\n", |
|
"mpl.get_websocket_type = function() {\n", |
|
" if (typeof(WebSocket) !== 'undefined') {\n", |
|
" return WebSocket;\n", |
|
" } else if (typeof(MozWebSocket) !== 'undefined') {\n", |
|
" return MozWebSocket;\n", |
|
" } else {\n", |
|
" alert('Your browser does not have WebSocket support.' +\n", |
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", |
|
" 'Firefox 4 and 5 are also supported but you ' +\n", |
|
" 'have to enable WebSockets in about:config.');\n", |
|
" };\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", |
|
" this.id = figure_id;\n", |
|
"\n", |
|
" this.ws = websocket;\n", |
|
"\n", |
|
" this.supports_binary = (this.ws.binaryType != undefined);\n", |
|
"\n", |
|
" if (!this.supports_binary) {\n", |
|
" var warnings = document.getElementById(\"mpl-warnings\");\n", |
|
" if (warnings) {\n", |
|
" warnings.style.display = 'block';\n", |
|
" warnings.textContent = (\n", |
|
" \"This browser does not support binary websocket messages. \" +\n", |
|
" \"Performance may be slow.\");\n", |
|
" }\n", |
|
" }\n", |
|
"\n", |
|
" this.imageObj = new Image();\n", |
|
"\n", |
|
" this.context = undefined;\n", |
|
" this.message = undefined;\n", |
|
" this.canvas = undefined;\n", |
|
" this.rubberband_canvas = undefined;\n", |
|
" this.rubberband_context = undefined;\n", |
|
" this.format_dropdown = undefined;\n", |
|
"\n", |
|
" this.image_mode = 'full';\n", |
|
"\n", |
|
" this.root = $('<div/>');\n", |
|
" this._root_extra_style(this.root)\n", |
|
" this.root.attr('style', 'display: inline-block');\n", |
|
"\n", |
|
" $(parent_element).append(this.root);\n", |
|
"\n", |
|
" this._init_header(this);\n", |
|
" this._init_canvas(this);\n", |
|
" this._init_toolbar(this);\n", |
|
"\n", |
|
" var fig = this;\n", |
|
"\n", |
|
" this.waiting = false;\n", |
|
"\n", |
|
" this.ws.onopen = function () {\n", |
|
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", |
|
" fig.send_message(\"send_image_mode\", {});\n", |
|
" fig.send_message(\"refresh\", {});\n", |
|
" }\n", |
|
"\n", |
|
" this.imageObj.onload = function() {\n", |
|
" if (fig.image_mode == 'full') {\n", |
|
" // Full images could contain transparency (where diff images\n", |
|
" // almost always do), so we need to clear the canvas so that\n", |
|
" // there is no ghosting.\n", |
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", |
|
" }\n", |
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n", |
|
" fig.waiting = false;\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", |
|
" 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", |
|
" 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", |
|
"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", |
|
"\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", |
|
" return false;\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", |
|
" if (name == 'download') {\n", |
|
" this.handle_save(this, null);\n", |
|
" } else {\n", |
|
" this.send_message(\"toolbar_button\", {name: name});\n", |
|
" }\n", |
|
"};\n", |
|
"\n", |
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", |
|
" this.message.textContent = tooltip;\n", |
|
"};\n", |
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", |
|
"\n", |
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", |
|
"\n", |
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", |
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n", |
|
" // object with the appropriate methods. Currently this is a non binary\n", |
|
" // socket, so there is still some room for performance tuning.\n", |
|
" var ws = {};\n", |
|
"\n", |
|
" ws.close = function() {\n", |
|
" comm.close()\n", |
|
" };\n", |
|
" ws.send = function(m) {\n", |
|
" //console.log('sending', m);\n", |
|
" comm.send(m);\n", |
|
" };\n", |
|
" // Register the callback with on_msg.\n", |
|
" comm.on_msg(function(msg) {\n", |
|
" //console.log('receiving', msg['content']['data'], msg);\n", |
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", |
|
" ws.onmessage(msg['content']['data'])\n", |
|
" });\n", |
|
" return ws;\n", |
|
"}\n", |
|
"\n", |
|
"mpl.mpl_figure_comm = function(comm, msg) {\n", |
|
" // This is the function which gets called when the mpl process\n", |
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", |
|
"\n", |
|
" var id = msg.content.data.id;\n", |
|
" // Get hold of the div created by the display call when the Comm\n", |
|
" // socket was opened in Python.\n", |
|
" var element = $(\"#\" + id);\n", |
|
" var ws_proxy = comm_websocket_adapter(comm)\n", |
|
"\n", |
|
" function ondownload(figure, format) {\n", |
|
" window.open(figure.imageObj.src);\n", |
|
" }\n", |
|
"\n", |
|
" var fig = new mpl.figure(id, ws_proxy,\n", |
|
" ondownload,\n", |
|
" element.get(0));\n", |
|
"\n", |
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", |
|
" // web socket which is closed, not our websocket->open comm proxy.\n", |
|
" ws_proxy.onopen();\n", |
|
"\n", |
|
" fig.parent_element = element.get(0);\n", |
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", |
|
" if (!fig.cell_info) {\n", |
|
" console.error(\"Failed to find cell for figure\", id, fig);\n", |
|
" return;\n", |
|
" }\n", |
|
"\n", |
|
" var output_index = fig.cell_info[2]\n", |
|
" var cell = fig.cell_info[0];\n", |
|
"\n", |
|
"};\n", |
|
"\n", |
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", |
|
" // 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.send_message('closing', {});\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-danger\" href=\"#\" title=\"Close figure\"><i class=\"fa fa-times icon-remove icon-large\"></i></button>');\n", |
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", |
|
" button.mouseover('Close figure', toolbar_mouse_event);\n", |
|
" buttongrp.append(button);\n", |
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", |
|
" titlebar.prepend(buttongrp);\n", |
|
"}\n", |
|
"\n", |
|
"\n", |
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n", |
|
" // this is important to make the div 'focusable\n", |
|
" el.attr('tabindex', 0)\n", |
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n", |
|
" // off when our div gets focus\n", |
|
"\n", |
|
" // location in version 3\n", |
|
" if (IPython.notebook.keyboard_manager) {\n", |
|
" IPython.notebook.keyboard_manager.register_events(el);\n", |
|
" }\n", |
|
" else {\n", |
|
" // location in version 2\n", |
|
" IPython.keyboard_manager.register_events(el);\n", |
|
" }\n", |
|
"\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", |
|
" var manager = IPython.notebook.keyboard_manager;\n", |
|
" if (!manager)\n", |
|
" manager = IPython.keyboard_manager;\n", |
|
"\n", |
|
" // Check for shift+enter\n", |
|
" if (event.shiftKey && event.which == 13) {\n", |
|
" this.canvas_div.blur();\n", |
|
" event.shiftKey = false;\n", |
|
" // Send a \"J\" for go to next cell\n", |
|
" event.which = 74;\n", |
|
" event.keyCode = 74;\n", |
|
" manager.command_mode();\n", |
|
" manager.handle_keydown(event);\n", |
|
" }\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", |
|
" fig.ondownload(fig, null);\n", |
|
"}\n", |
|
"\n", |
|
"\n", |
|
"mpl.find_output_cell = function(html_output) {\n", |
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", |
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", |
|
" // IPython event is triggered only after the cells have been serialised, which for\n", |
|
" // our purposes (turning an active figure into a static one), is too late.\n", |
|
" var cells = IPython.notebook.get_cells();\n", |
|
" var ncells = cells.length;\n", |
|
" for (var i=0; i<ncells; i++) {\n", |
|
" var cell = cells[i];\n", |
|
" if (cell.cell_type === 'code'){\n", |
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", |
|
" var data = cell.output_area.outputs[j];\n", |
|
" if (data.data) {\n", |
|
" // IPython >= 3 moved mimebundle to data attribute of output\n", |
|
" data = data.data;\n", |
|
" }\n", |
|
" if (data['text/html'] == html_output) {\n", |
|
" return [cell, data, j];\n", |
|
" }\n", |
|
" }\n", |
|
" }\n", |
|
" }\n", |
|
"}\n", |
|
"\n", |
|
"// Register the function which deals with the matplotlib target/channel.\n", |
|
"// The kernel may be null if the page has been refreshed.\n", |
|
"if (IPython.notebook.kernel != null) {\n", |
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", |
|
"}\n" |
|
], |
|
"text/plain": [ |
|
"<IPython.core.display.Javascript object>" |
|
] |
|
}, |
|
"metadata": {}, |
|
"output_type": "display_data" |
|
}, |
|
{ |
|
"data": { |
|
"text/html": [ |
|
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAYAAAB91L6VAAAgAElEQVR4XuydB5hU1fmH39nGLgs7S116ryJFsdckYovBLlFjS2LvJRpLYkliYkkssSQxakxILGjUGBsixQIBsWNXQEBEOrOwlK3/5xvuzf9mnMXdnbM7d3Z+93nm2WWZe+657zlzf/N95zvfF0GHCIiACIiACIhAixOItPgVdUEREAEREAEREAEkwJoEIiACIiACIpAGAhLgNEDXJUVABERABERAAqw5IAIiIAIiIAJpICABTgN0XVIEREAEREAEJMCaAyIgAiIgAiKQBgIS4DRA1yVFQAREQAREQAKsOSACIiACIiACaSAgAU4DdF1SBERABERABCTAmgMiIAIiIAIikAYCEuA0QNclRUAEREAEREACrDkgAiIgAiIgAmkgIAFOA3RdUgREQAREQAQkwJoDIiACIiACIpAGAhLgNEDXJUVABERABERAAqw5IAIiIAIiIAJpICABTgN0XVIEREAEREAEJMCaAyIgAiIgAiKQBgIS4DRA1yVFQAREQAREQAKsOSACIiACIiACaSAgAU4DdF1SBERABERABCTAmgMiIAIiIAIikAYCEuA0QNclRUAEREAEREACrDkgAiIgAiIgAmkgIAFOA3RdUgREQAREQAQkwJoDIiACIiACIpAGAhLgNEDXJUVABERABERAAqw5IAIiIAIiIAJpICABTgN0XVIEREAEREAEJMCaAyIgAiIgAiKQBgIS4DRA1yVFQAREQAREQAKsOSACIiACIiACaSAgAU4DdF1SBERABERABCTAmgMiIAIiIAIikAYCEuA0QNclRUAEREAEREACrDkgAiIgAiIgAmkgIAFOA3RdUgREQAREQAQkwJoDIiACIiACIpAGAhLgNEDXJUVABERABERAAqw5IAIiIAIiIAJpICABTgN0XVIEREAEREAEJMCaAyIgAiIgAiKQBgIS4DRA1yVFQAREoJUQOBY4BxgFtAfygNpt3FsH4E7gEKAOeMY7P9ZKeDTqNiTAjcKlN4uACIiACAQIHACYqLYF7muAAJvg5gMm3KY/DwMVwOHZSFUCnI2jrnsWAREQAbcEvgVM+wYB7gssBEYD87zLm+X8NtAH+MJtl8LfmgQ4/GOkHoqACIhA2Ak0RIAP8yzeooSb2QwcDTwd9pt03T8JsGui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\">" |
|
], |
|
"text/plain": [ |
|
"<IPython.core.display.HTML object>" |
|
] |
|
}, |
|
"metadata": {}, |
|
"output_type": "display_data" |
|
} |
|
], |
|
"source": [ |
|
"phiviewer = fp.Viewer(vars=phi, datamin=-1, datamax=1)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 21, |
|
"metadata": { |
|
"scrolled": true |
|
}, |
|
"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", |
|
" fig.waiting = false;\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", |
|
" 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", |
|
" 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", |
|
"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", |
|
"\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", |
|
" return false;\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n", |
|
" if (name == 'download') {\n", |
|
" this.handle_save(this, null);\n", |
|
" } else {\n", |
|
" this.send_message(\"toolbar_button\", {name: name});\n", |
|
" }\n", |
|
"};\n", |
|
"\n", |
|
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n", |
|
" this.message.textContent = tooltip;\n", |
|
"};\n", |
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", |
|
"\n", |
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", |
|
"\n", |
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n", |
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n", |
|
" // object with the appropriate methods. Currently this is a non binary\n", |
|
" // socket, so there is still some room for performance tuning.\n", |
|
" var ws = {};\n", |
|
"\n", |
|
" ws.close = function() {\n", |
|
" comm.close()\n", |
|
" };\n", |
|
" ws.send = function(m) {\n", |
|
" //console.log('sending', m);\n", |
|
" comm.send(m);\n", |
|
" };\n", |
|
" // Register the callback with on_msg.\n", |
|
" comm.on_msg(function(msg) {\n", |
|
" //console.log('receiving', msg['content']['data'], msg);\n", |
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n", |
|
" ws.onmessage(msg['content']['data'])\n", |
|
" });\n", |
|
" return ws;\n", |
|
"}\n", |
|
"\n", |
|
"mpl.mpl_figure_comm = function(comm, msg) {\n", |
|
" // This is the function which gets called when the mpl process\n", |
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n", |
|
"\n", |
|
" var id = msg.content.data.id;\n", |
|
" // Get hold of the div created by the display call when the Comm\n", |
|
" // socket was opened in Python.\n", |
|
" var element = $(\"#\" + id);\n", |
|
" var ws_proxy = comm_websocket_adapter(comm)\n", |
|
"\n", |
|
" function ondownload(figure, format) {\n", |
|
" window.open(figure.imageObj.src);\n", |
|
" }\n", |
|
"\n", |
|
" var fig = new mpl.figure(id, ws_proxy,\n", |
|
" ondownload,\n", |
|
" element.get(0));\n", |
|
"\n", |
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", |
|
" // web socket which is closed, not our websocket->open comm proxy.\n", |
|
" ws_proxy.onopen();\n", |
|
"\n", |
|
" fig.parent_element = element.get(0);\n", |
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n", |
|
" if (!fig.cell_info) {\n", |
|
" console.error(\"Failed to find cell for figure\", id, fig);\n", |
|
" return;\n", |
|
" }\n", |
|
"\n", |
|
" var output_index = fig.cell_info[2]\n", |
|
" var cell = fig.cell_info[0];\n", |
|
"\n", |
|
"};\n", |
|
"\n", |
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n", |
|
" // 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.send_message('closing', {});\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-danger\" href=\"#\" title=\"Close figure\"><i class=\"fa fa-times icon-remove icon-large\"></i></button>');\n", |
|
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n", |
|
" button.mouseover('Close figure', toolbar_mouse_event);\n", |
|
" buttongrp.append(button);\n", |
|
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", |
|
" titlebar.prepend(buttongrp);\n", |
|
"}\n", |
|
"\n", |
|
"\n", |
|
"mpl.figure.prototype._canvas_extra_style = function(el){\n", |
|
" // this is important to make the div 'focusable\n", |
|
" el.attr('tabindex', 0)\n", |
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n", |
|
" // off when our div gets focus\n", |
|
"\n", |
|
" // location in version 3\n", |
|
" if (IPython.notebook.keyboard_manager) {\n", |
|
" IPython.notebook.keyboard_manager.register_events(el);\n", |
|
" }\n", |
|
" else {\n", |
|
" // location in version 2\n", |
|
" IPython.keyboard_manager.register_events(el);\n", |
|
" }\n", |
|
"\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype._key_event_extra = function(event, name) {\n", |
|
" var manager = IPython.notebook.keyboard_manager;\n", |
|
" if (!manager)\n", |
|
" manager = IPython.keyboard_manager;\n", |
|
"\n", |
|
" // Check for shift+enter\n", |
|
" if (event.shiftKey && event.which == 13) {\n", |
|
" this.canvas_div.blur();\n", |
|
" event.shiftKey = false;\n", |
|
" // Send a \"J\" for go to next cell\n", |
|
" event.which = 74;\n", |
|
" event.keyCode = 74;\n", |
|
" manager.command_mode();\n", |
|
" manager.handle_keydown(event);\n", |
|
" }\n", |
|
"}\n", |
|
"\n", |
|
"mpl.figure.prototype.handle_save = function(fig, msg) {\n", |
|
" fig.ondownload(fig, null);\n", |
|
"}\n", |
|
"\n", |
|
"\n", |
|
"mpl.find_output_cell = function(html_output) {\n", |
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n", |
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", |
|
" // IPython event is triggered only after the cells have been serialised, which for\n", |
|
" // our purposes (turning an active figure into a static one), is too late.\n", |
|
" var cells = IPython.notebook.get_cells();\n", |
|
" var ncells = cells.length;\n", |
|
" for (var i=0; i<ncells; i++) {\n", |
|
" var cell = cells[i];\n", |
|
" if (cell.cell_type === 'code'){\n", |
|
" for (var j=0; j<cell.output_area.outputs.length; j++) {\n", |
|
" var data = cell.output_area.outputs[j];\n", |
|
" if (data.data) {\n", |
|
" // IPython >= 3 moved mimebundle to data attribute of output\n", |
|
" data = data.data;\n", |
|
" }\n", |
|
" if (data['text/html'] == html_output) {\n", |
|
" return [cell, data, j];\n", |
|
" }\n", |
|
" }\n", |
|
" }\n", |
|
" }\n", |
|
"}\n", |
|
"\n", |
|
"// Register the function which deals with the matplotlib target/channel.\n", |
|
"// The kernel may be null if the page has been refreshed.\n", |
|
"if (IPython.notebook.kernel != null) {\n", |
|
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", |
|
"}\n" |
|
], |
|
"text/plain": [ |
|
"<IPython.core.display.Javascript object>" |
|
] |
|
}, |
|
"metadata": {}, |
|
"output_type": "display_data" |
|
}, |
|
{ |
|
"data": { |
|
"text/html": [ |
|
"<img src=\"data:image/png;base64,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\">" |
|
], |
|
"text/plain": [ |
|
"<IPython.core.display.HTML object>" |
|
] |
|
}, |
|
"metadata": {}, |
|
"output_type": "display_data" |
|
}, |
|
{ |
|
"name": "stderr", |
|
"output_type": "stream", |
|
"text": [ |
|
"/Users/guyer/Documents/research/FiPy/fipy/fipy/variables/variable.py:1170: RuntimeWarning: divide by zero encountered in divide\n", |
|
" return self._BinaryOperatorVariable(lambda a,b: b/a, other)\n", |
|
"/Users/guyer/Documents/research/FiPy/fipy/fipy/variables/variable.py:1151: RuntimeWarning: invalid value encountered in multiply\n", |
|
" return self._BinaryOperatorVariable(lambda a,b: a*b, other)\n" |
|
] |
|
} |
|
], |
|
"source": [ |
|
"radviewer = fp.Viewer(vars=radius *(1 + phi) * (1-phi), datamin=-20, datamax=0)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 22, |
|
"metadata": {}, |
|
"outputs": [], |
|
"source": [ |
|
"radviewer.plot()" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": 23, |
|
"metadata": { |
|
"scrolled": true |
|
}, |
|
"outputs": [ |
|
{ |
|
"ename": "KeyboardInterrupt", |
|
"evalue": "", |
|
"output_type": "error", |
|
"traceback": [ |
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", |
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", |
|
"\u001b[0;32m<ipython-input-23-b46aded2fd6d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msweep\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mueq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mphieq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m.05\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;31m# res = eq.sweep(dt=.1)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;31m# print res\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/terms/term.pyc\u001b[0m in \u001b[0;36msolve\u001b[0;34m(self, var, solver, boundaryConditions, dt)\u001b[0m\n\u001b[1;32m 209\u001b[0m \"\"\"\n\u001b[1;32m 210\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 211\u001b[0;31m \u001b[0msolver\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_prepareLinearSystem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msolver\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mboundaryConditions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 212\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0msolver\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_solve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/terms/term.pyc\u001b[0m in \u001b[0;36m_prepareLinearSystem\u001b[0;34m(self, var, solver, boundaryConditions, dt)\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0mtransientGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getTransientGeomCoeff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[0mdiffusionGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getDiffusionGeomCoeff\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvar\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 170\u001b[0;31m buildExplicitIfOther=self._buildExplcitIfOther)\n\u001b[0m\u001b[1;32m 171\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 172\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_buildCache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mRHSvector\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/terms/binaryTerm.pyc\u001b[0m in \u001b[0;36m_buildAndAddMatrices\u001b[0;34m(self, var, SparseMatrix, boundaryConditions, dt, transientGeomCoeff, diffusionGeomCoeff, buildExplicitIfOther)\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[0mtransientGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtransientGeomCoeff\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0mdiffusionGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdiffusionGeomCoeff\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 68\u001b[0;31m buildExplicitIfOther=buildExplicitIfOther)\n\u001b[0m\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0mmatrix\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtmpMatrix\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/terms/binaryTerm.pyc\u001b[0m in \u001b[0;36m_buildAndAddMatrices\u001b[0;34m(self, var, SparseMatrix, boundaryConditions, dt, transientGeomCoeff, diffusionGeomCoeff, buildExplicitIfOther)\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[0mtransientGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtransientGeomCoeff\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0mdiffusionGeomCoeff\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdiffusionGeomCoeff\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 68\u001b[0;31m buildExplicitIfOther=buildExplicitIfOther)\n\u001b[0m\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0mmatrix\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtmpMatrix\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/terms/binaryTerm.pyc\u001b[0m in \u001b[0;36m_buildAndAddMatrices\u001b[0;34m(self, var, SparseMatrix, boundaryConditions, dt, transientGeomCoeff, diffusionGeomCoeff, buildExplicitIfOther)\u001b[0m\n\u001b[1;32m 68\u001b[0m buildExplicitIfOther=buildExplicitIfOther)\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 70\u001b[0;31m \u001b[0mmatrix\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtmpMatrix\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 71\u001b[0m \u001b[0mRHSvector\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mtmpRHSvector\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/matrices/pysparseMatrix.pyc\u001b[0m in \u001b[0;36m__iadd__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__iadd__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 71\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_iadd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 72\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;32m/Users/guyer/Documents/research/FiPy/fipy/fipy/matrices/pysparseMatrix.pyc\u001b[0m in \u001b[0;36m_iadd\u001b[0;34m(self, L, other, sign)\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_iadd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mL\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msign\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 75\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mother\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 76\u001b[0;31m \u001b[0mL\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshift\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msign\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 77\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 78\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__add__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", |
|
"\u001b[0;31mKeyboardInterrupt\u001b[0m: " |
|
] |
|
} |
|
], |
|
"source": [ |
|
"for step in xrange(1000000):\n", |
|
" phi.updateOld()\n", |
|
" u.updateOld()\n", |
|
" for sweep in range(3):\n", |
|
" ueq.solve(dt=.05)\n", |
|
" phieq.solve(dt=.05)\n", |
|
"# res = eq.sweep(dt=.1)\n", |
|
"# print res\n", |
|
" if step % 10 == 0:\n", |
|
"# radviewer.plot()\n", |
|
" phiviewer.plot()\n", |
|
"# tsv.plot(filename=\"%d.txt.gz\" % step)" |
|
] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [] |
|
}, |
|
{ |
|
"cell_type": "code", |
|
"execution_count": null, |
|
"metadata": { |
|
"collapsed": true |
|
}, |
|
"outputs": [], |
|
"source": [] |
|
} |
|
], |
|
"metadata": { |
|
"kernelspec": { |
|
"display_name": "Python 2", |
|
"language": "python", |
|
"name": "python2" |
|
}, |
|
"language_info": { |
|
"codemirror_mode": { |
|
"name": "ipython", |
|
"version": 2 |
|
}, |
|
"file_extension": ".py", |
|
"mimetype": "text/x-python", |
|
"name": "python", |
|
"nbconvert_exporter": "python", |
|
"pygments_lexer": "ipython2", |
|
"version": "2.7.13" |
|
} |
|
}, |
|
"nbformat": 4, |
|
"nbformat_minor": 1 |
|
} |