# Fourier Analysis

## Introduction

This is a tutorial on some Fourier Analysis topics using SymPy and Python.

This notebook uses ipywidgets to create some interactive widgets. Refer to the installation guide if needed.



In [1]:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from mpl_toolkits.mplot3d import Axes3D
from sympy import *
from ipywidgets import interact, fixed
from IPython.display import display




In [2]:

%matplotlib notebook
init_session()




IPython console for SymPy 1.2 (Python 3.6.8-64-bit) (ground types: gmpy)

These commands were executed:
>>> from __future__ import division
>>> from sympy import *
>>> x, y, z, t = symbols('x y z t')
>>> k, m, n = symbols('k m n', integer=True)
>>> f, g, h = symbols('f g h', cls=Function)
>>> init_printing()

Documentation can be found at http://docs.sympy.org/1.2/




In [3]:

plt.style.use(u"seaborn-notebook")
plt.rcParams["figure.figsize"] = 6, 4



## Fourier Series

### An example

Let's start with some examples of Fourier series approximation of common periodic signals, namely:

• Square;
• Sawtooth;
• Triangle; and
• Circle (semicircle, actually).


In [4]:

from scipy.special import j1

def waves(N=10, f=1, wtype='square'):
"""Plot the Fourier series approximation for a signal

N is the number of terms to consider in the approximation,
f is the frequency of the signal, and wtype is the type of
signal, the options are ('square','sawtooth','triangle','circ').
"""

t = np.linspace(0, 2, 1000)
x = np.zeros_like(t)

for k in range(1, N+1):
if wtype=='square':
x = x + 4/np.pi*np.sin(2*np.pi*(2*k - 1)*f*t)/(2*k-1)
if wtype=='sawtooth':
x = x + 2*(-1)**(k+1)/np.pi*np.sin(2*np.pi*k*f*t)/k
if wtype=='triangle':
n = k - 1
x = x + 8/np.pi**2*(-1)**n*np.sin(2*np.pi*(2*n + 1)*f*t)/(2*n +1)**2
if wtype=='circ':
n = k - 1
if n == 0:
x = x + 0.25*np.pi
else:
x = x + (-1)**n*j1(n*np.pi)/n*np.cos(2*np.pi*n*f*t)

plt.subplots(figsize=(6,4))
plt.plot(t, x, linewidth=2, color="#e41a1c")
plt.ylim(-1.5, 1.5)




In [5]:

w = interact(waves,
N=(1,400),
f=(1.,10.),
wtype=['square','sawtooth','triangle','circ'])




var element = $('#3105de29-c3f0-40f9-ad68-640490d3ac3d'); {"model_id": "1de60b6d38a34615818578fa17fcb006", "version_major": 2, "version_minor": 0}  ## Using Sympy In the previous example, we hardcoded the representation of the signal. This example take advantage of the function fourier_series that returns the Fourier series for a given function. To get the approximated version (with n terms) we can use the method .truncate(n).  In [6]: def fourier(fun, approx_fun, half_width=pi, n=5): """ Plot the Fourier series approximation using Sympy Parameters ---------- fun : Sympy expression Original function. approx_fun : Sympy FourierSeries Fourier Series representation of fun. hald_width : Sympy "number" Half-period of the signal. n : integer Number of terms to consider. """ fun_np = lambdify((x), fun, "numpy") approx_np = lambdify((x), approx_fun.truncate(n), "numpy") x_np = np.linspace(-float(half_width), float(half_width), 201) plt.subplots(figsize=(6,4)) plt.plot(x_np, fun_np(x_np), color="#e41a1c", linewidth=2, label="Function") plt.plot(x_np, approx_np(x_np), color="black", linestyle="dashed", linewidth=2, label="Approximation") plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.)   In [7]: fun = x**2 approx_fun = fourier_series(x**2, (x, -pi, pi))   In [8]: interact(fourier, fun=fixed(fun), approx_fun=fixed(approx_fun), half_width=fixed(1), n=(1, 50));   var element =$('#c4c13c40-05fb-4990-969f-e648b35ecfb8');

{"model_id": "259ec980449141d0b8336a6eb79f7444", "version_major": 2, "version_minor": 0}



We can also represent functions in several variables.

The next example shows the Fourier representation of a (rotated) hyperbolic paraboloid.



In [9]:

def fourier2D_xy(m_terms=5, n_terms=5):
"""Plot the 2D Fourier approximation for a hyperbolic paraboloid

m_terms, and n_terms are the number of terms in x and y.

The values are padded to be between [-0.9 pi, 0.9 pi] to avoid the
discontinuities in the border of the domain.
"""
Y, X = 0.9*np.pi * np.mgrid[-1:1:21j, -1:1:21j]
XY = np.zeros_like(X)
for cont_x in range(1, m_terms + 1):
for cont_y in range(1, n_terms + 1):
XY = XY + (-1)**(cont_x + cont_y) * \
np.sin(cont_x*X) * np.sin(cont_y*Y)/(cont_x*cont_y)

XY = 4*XY

fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, XY, cmap="Purples_r", cstride=1, rstride=1, alpha=0.8,
lw=0.2)
ax.plot_wireframe(X, Y, X*Y, cstride=1, rstride=1, color="#e41a1c",
linewidth=1)




In [10]:

interact(fourier2D_xy,
m_terms=(1, 50),
n_terms=(1, 50));




var element = $('#f462a05c-8e35-48ab-98f1-5ee3e864eaf8'); {"model_id": "c25e3fca92d649a682d5af094c09aa7e", "version_major": 2, "version_minor": 0}  ## Fourier transforms First, let's compute the Fourier Tranform of a Gaussian function.  In [11]: f = exp(-x**2) F = fourier_transform(f, x, y) F   Out[11]: $$\sqrt{\pi} e^{- \pi^{2} y^{2}}$$  Let's compute the Fourier transform of a square function  In [12]: y = symbols("y", positive=True)   In [13]: square = Piecewise((0, x<-S(1)/2), (0, x>S(1)/2), (1, True)) T_square = fourier_transform(square, x, y) T_square = simplify(T_square.rewrite(sin)) T_square   Out[13]: $$\frac{\sin{\left (\pi y \right )}}{\pi y}$$   In [14]: plot(T_square);   var element =$('#b04d396c-d3de-47d9-bbc3-24717a976562');
/* Put everything inside the global mpl namespace */
window.mpl = {};

mpl.get_websocket_type = function() {
if (typeof(WebSocket) !== 'undefined') {
return WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
return MozWebSocket;
} else {
alert('Your browser does not have WebSocket support.' +
'Please try Chrome, Safari or Firefox ≥ 6. ' +
'Firefox 4 and 5 are also supported but you ' +
'have to enable WebSockets in about:config.');
};
}

mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
this.id = figure_id;

this.ws = websocket;

this.supports_binary = (this.ws.binaryType != undefined);

if (!this.supports_binary) {
var warnings = document.getElementById("mpl-warnings");
if (warnings) {
warnings.style.display = 'block';
warnings.textContent = (
"This browser does not support binary websocket messages. " +
"Performance may be slow.");
}
}

this.imageObj = new Image();

this.context = undefined;
this.message = undefined;
this.canvas = undefined;
this.rubberband_canvas = undefined;
this.rubberband_context = undefined;
this.format_dropdown = undefined;

this.image_mode = 'full';

this.root = $('<div/>'); this._root_extra_style(this.root) this.root.attr('style', 'display: inline-block');$(parent_element).append(this.root);

this._init_canvas(this);
this._init_toolbar(this);

var fig = this;

this.waiting = false;

this.ws.onopen =  function () {
fig.send_message("supports_binary", {value: fig.supports_binary});
fig.send_message("send_image_mode", {});
if (mpl.ratio != 1) {
fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
}
fig.send_message("refresh", {});
}

this.imageObj.onload = function() {
if (fig.image_mode == 'full') {
// Full images could contain transparency (where diff images
// almost always do), so we need to clear the canvas so that
// there is no ghosting.
fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
}
fig.context.drawImage(fig.imageObj, 0, 0);
};

this.imageObj.onunload = function() {
fig.ws.close();
}

this.ws.onmessage = this._make_on_message_function(this);

}

mpl.figure.prototype._init_header = function() {
var titlebar = $( '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + 'ui-helper-clearfix"/>'); var titletext =$(
'<div class="ui-dialog-title" style="width: 100%; ' +
'text-align: center; padding: 3px;"/>');
titlebar.append(titletext)
this.root.append(titlebar);
}

mpl.figure.prototype._canvas_extra_style = function(canvas_div) {

}

mpl.figure.prototype._root_extra_style = function(canvas_div) {

}

mpl.figure.prototype._init_canvas = function() {
var fig = this;

var canvas_div = $('<div/>'); canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); function canvas_keyboard_event(event) { return fig.key_event(event, event['data']); } canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); this.canvas_div = canvas_div this._canvas_extra_style(canvas_div) this.root.append(canvas_div); var canvas =$('<canvas/>');
canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")

this.canvas = canvas[0];
this.context = canvas[0].getContext("2d");

var backingStore = this.context.backingStorePixelRatio ||
this.context.webkitBackingStorePixelRatio ||
this.context.mozBackingStorePixelRatio ||
this.context.msBackingStorePixelRatio ||
this.context.oBackingStorePixelRatio ||
this.context.backingStorePixelRatio || 1;

mpl.ratio = (window.devicePixelRatio || 1) / backingStore;

var rubberband = $('<canvas/>'); rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") var pass_mouse_events = true; canvas_div.resizable({ start: function(event, ui) { pass_mouse_events = false; }, resize: function(event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, stop: function(event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { if (pass_mouse_events) return fig.mouse_event(event, event['data']); } rubberband.mousedown('button_press', mouse_event_fn); rubberband.mouseup('button_release', mouse_event_fn); // Throttle sequential mouse events to 1 every 20ms. rubberband.mousemove('motion_notify', mouse_event_fn); rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); canvas_div.on("wheel", function (event) { event = event.originalEvent; event['data'] = 'scroll' if (event.deltaY < 0) { event.step = 1; } else { event.step = -1; } mouse_event_fn(event); }); canvas_div.append(canvas); canvas_div.append(rubberband); this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; this.rubberband_context = rubberband[0].getContext("2d"); this.rubberband_context.strokeStyle = "#000000"; this._resize_canvas = function(width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. canvas_div.css('width', width) canvas_div.css('height', height) canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); rubberband.attr('width', width); rubberband.attr('height', height); } // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu.$(this.rubberband_canvas).bind("contextmenu",function(e){
return false;
});

function set_focus () {
canvas.focus();
canvas_div.focus();
}

window.setTimeout(set_focus, 100);
}

mpl.figure.prototype._init_toolbar = function() {
var fig = this;

var nav_element = $('<div/>') nav_element.attr('style', 'width: 100%'); this.root.append(nav_element); // Define a callback function for later on. function toolbar_event(event) { return fig.toolbar_button_onclick(event['data']); } function toolbar_mouse_event(event) { return fig.toolbar_button_onmouseover(event['data']); } for(var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; var method_name = mpl.toolbar_items[toolbar_ind][3]; if (!name) { // put a spacer in here. continue; } var button =$('<button/>');
button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
'ui-button-icon-only');
button.attr('role', 'button');
button.attr('aria-disabled', 'false');
button.click(method_name, toolbar_event);
button.mouseover(tooltip, toolbar_mouse_event);

var icon_img = $('<span/>'); icon_img.addClass('ui-button-icon-primary ui-icon'); icon_img.addClass(image); icon_img.addClass('ui-corner-all'); var tooltip_span =$('<span/>');
tooltip_span.html(tooltip);

button.append(icon_img);
button.append(tooltip_span);

nav_element.append(button);
}

var fmt_picker_span = $('<span/>'); var fmt_picker =$('<select/>');
fmt_picker_span.append(fmt_picker);
nav_element.append(fmt_picker_span);
this.format_dropdown = fmt_picker[0];

for (var ind in mpl.extensions) {
var fmt = mpl.extensions[ind];
var option = $( '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); fmt_picker.append(option) } // Add hover states to the ui-buttons$( ".ui-button" ).hover(
function() { $(this).addClass("ui-state-hover");}, function() {$(this).removeClass("ui-state-hover");}
);

var status_bar = $('<span class="mpl-message"/>'); nav_element.append(status_bar); this.message = status_bar[0]; } mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); } mpl.figure.prototype.send_message = function(type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); } mpl.figure.prototype.send_draw_message = function() { if (!this.waiting) { this.waiting = true; this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); } } mpl.figure.prototype.handle_save = function(fig, msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); } mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { fig._resize_canvas(size[0], size[1]); fig.send_message("refresh", {}); }; } mpl.figure.prototype.handle_rubberband = function(fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; x0 = Math.floor(x0) + 0.5; y0 = Math.floor(y0) + 0.5; x1 = Math.floor(x1) + 0.5; y1 = Math.floor(y1) + 0.5; var min_x = Math.min(x0, x1); var min_y = Math.min(y0, y1); var width = Math.abs(x1 - x0); var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( 0, 0, fig.canvas.width, fig.canvas.height); fig.rubberband_context.strokeRect(min_x, min_y, width, height); } mpl.figure.prototype.handle_figure_label = function(fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; } mpl.figure.prototype.handle_cursor = function(fig, msg) { var cursor = msg['cursor']; switch(cursor) { case 0: cursor = 'pointer'; break; case 1: cursor = 'default'; break; case 2: cursor = 'crosshair'; break; case 3: cursor = 'move'; break; } fig.rubberband_canvas.style.cursor = cursor; } mpl.figure.prototype.handle_message = function(fig, msg) { fig.message.textContent = msg['message']; } mpl.figure.prototype.handle_draw = function(fig, msg) { // Request the server to send over a new figure. fig.send_draw_message(); } mpl.figure.prototype.handle_image_mode = function(fig, msg) { fig.image_mode = msg['mode']; } mpl.figure.prototype.updated_canvas_event = function() { // Called whenever the canvas gets updated. this.send_message("ack", {}); } // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. mpl.figure.prototype._make_on_message_function = function(fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ evt.data.type = "image/png"; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( fig.imageObj.src); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( evt.data); fig.updated_canvas_event(); fig.waiting = false; return; } else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; return; } var msg = JSON.parse(evt.data); var msg_type = msg['type']; // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { var callback = fig["handle_" + msg_type]; } catch (e) { console.log("No handler for the '" + msg_type + "' message type: ", msg); return; } if (callback) { try { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); } } }; } // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas mpl.findpos = function(e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; if (!e) e = window.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) // defeat Safari bug targ = targ.parentNode; // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document // offset() returns the position of the element relative to the document var x = e.pageX -$(targ).offset().left;
var y = e.pageY - $(targ).offset().top; return {"x": x, "y": y}; }; /* * return a copy of an object with only non-object keys * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { if (typeof original[key] !== 'object') obj[key] = original[key] return obj; }, {}); } mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; this.send_message(name, {x: x, y: y, button: event.button, step: event.step, guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want * to control all of the cursor setting manually through the * 'cursor' event from matplotlib */ event.preventDefault(); return false; } mpl.figure.prototype._key_event_extra = function(event, name) { // Handle any extra behaviour associated with a key event } mpl.figure.prototype.key_event = function(event, name) { // Prevent repeat events if (name == 'key_press') { if (event.which === this._key) return; else this._key = event.which; } if (name == 'key_release') this._key = null; var value = ''; if (event.ctrlKey && event.which != 17) value += "ctrl+"; if (event.altKey && event.which != 18) value += "alt+"; if (event.shiftKey && event.which != 16) value += "shift+"; value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); this.send_message(name, {key: value, guiEvent: simpleKeys(event)}); return false; } mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } }; mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { this.message.textContent = tooltip; }; 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"]]; mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"]; mpl.default_extension = "png";var comm_websocket_adapter = function(comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; ws.close = function() { comm.close() }; ws.send = function(m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. comm.on_msg(function(msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. ws.onmessage(msg['content']['data']) }); return ws; } mpl.mpl_figure_comm = function(comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. var element =$("#" + id);
var ws_proxy = comm_websocket_adapter(comm)

window.open(figure.imageObj.src);
}

var fig = new mpl.figure(id, ws_proxy,
element.get(0));

// Call onopen now - mpl needs it, as it is assuming we've passed it a real
// web socket which is closed, not our websocket->open comm proxy.
ws_proxy.onopen();

fig.parent_element = element.get(0);
fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
if (!fig.cell_info) {
console.error("Failed to find cell for figure", id, fig);
return;
}

var output_index = fig.cell_info[2]
var cell = fig.cell_info[0];

};

mpl.figure.prototype.handle_close = function(fig, msg) {
var width = fig.canvas.width/mpl.ratio
fig.root.unbind('remove')

// Update the output cell to use the data from the current canvas.
fig.push_to_output();
var dataURL = fig.canvas.toDataURL();
// Re-enable the keyboard manager in IPython - without this line, in FF,
// the notebook keyboard shortcuts fail.
IPython.keyboard_manager.enable()
$(fig.parent_element).html('<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'); fig.close_ws(fig, msg); } mpl.figure.prototype.close_ws = function(fig, msg){ fig.send_message('closing', msg); // fig.ws.close() } mpl.figure.prototype.push_to_output = function(remove_interactive) { // Turn the data on the canvas into data in the output cell. var width = this.canvas.width/mpl.ratio var dataURL = this.canvas.toDataURL(); this.cell_info[1]['text/html'] = '<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'; } mpl.figure.prototype.updated_canvas_event = function() { // Tell IPython that the notebook contents must change. IPython.notebook.set_dirty(true); this.send_message("ack", {}); var fig = this; // Wait a second, then push the new image to the DOM so // that it is saved nicely (might be nice to debounce this). setTimeout(function () { fig.push_to_output() }, 1000); } mpl.figure.prototype._init_toolbar = function() { var fig = this; var nav_element =$('<div/>')
nav_element.attr('style', 'width: 100%');
this.root.append(nav_element);

// Define a callback function for later on.
function toolbar_event(event) {
return fig.toolbar_button_onclick(event['data']);
}
function toolbar_mouse_event(event) {
return fig.toolbar_button_onmouseover(event['data']);
}

for(var toolbar_ind in mpl.toolbar_items){
var name = mpl.toolbar_items[toolbar_ind][0];
var tooltip = mpl.toolbar_items[toolbar_ind][1];
var image = mpl.toolbar_items[toolbar_ind][2];
var method_name = mpl.toolbar_items[toolbar_ind][3];

if (!name) { continue; };

var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); button.click(method_name, toolbar_event); button.mouseover(tooltip, toolbar_mouse_event); nav_element.append(button); } // Add the status bar. var status_bar =$('<span class="mpl-message" style="text-align:right; float: right;"/>');
nav_element.append(status_bar);
this.message = status_bar[0];

// Add the close button to the window.
var buttongrp = $('<div class="btn-group inline pull-right"></div>'); 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>');
button.click(function (evt) { fig.handle_close(fig, {}); } );
button.mouseover('Stop Interaction', toolbar_mouse_event);
buttongrp.append(button);
var titlebar = this.root.find($('.ui-dialog-titlebar')); titlebar.prepend(buttongrp); } mpl.figure.prototype._root_extra_style = function(el){ var fig = this el.on("remove", function(){ fig.close_ws(fig, {}); }); } mpl.figure.prototype._canvas_extra_style = function(el){ // this is important to make the div 'focusable el.attr('tabindex', 0) // reach out to IPython and tell the keyboard manager to turn it's self // off when our div gets focus // location in version 3 if (IPython.notebook.keyboard_manager) { IPython.notebook.keyboard_manager.register_events(el); } else { // location in version 2 IPython.keyboard_manager.register_events(el); } } mpl.figure.prototype._key_event_extra = function(event, name) { var manager = IPython.notebook.keyboard_manager; if (!manager) manager = IPython.keyboard_manager; // Check for shift+enter if (event.shiftKey && event.which == 13) { this.canvas_div.blur(); event.shiftKey = false; // Send a "J" for go to next cell event.which = 74; event.keyCode = 74; manager.command_mode(); manager.handle_keydown(event); } } mpl.figure.prototype.handle_save = function(fig, msg) { fig.ondownload(fig, null); } mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" // IPython event is triggered only after the cells have been serialised, which for // our purposes (turning an active figure into a static one), is too late. var cells = IPython.notebook.get_cells(); var ncells = cells.length; for (var i=0; i<ncells; i++) { var cell = cells[i]; if (cell.cell_type === 'code'){ for (var j=0; j<cell.output_area.outputs.length; j++) { var data = cell.output_area.outputs[j]; if (data.data) { // IPython >= 3 moved mimebundle to data attribute of output data = data.data; } if (data['text/html'] == html_output) { return [cell, data, j]; } } } } } // Register the function which deals with the matplotlib target/channel. // The kernel may be null if the page has been refreshed. if (IPython.notebook.kernel != null) { IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); }  We can explicitly solve the last integral  In [15]: y = symbols("y", nonzero=True) FT = integrate(exp(-2*pi*I*x*y), (x, -S(1)/2, S(1)/2))   In [16]: FT = simplify(FT.rewrite(sin)) FT   Out[16]: $$\frac{\sin{\left (\pi y \right )}}{\pi y}$$   In [17]: plot(FT);   var element =$('#18d7ae1d-13f0-4e68-83ad-6bd5bc4f8311');
/* Put everything inside the global mpl namespace */
window.mpl = {};

mpl.get_websocket_type = function() {
if (typeof(WebSocket) !== 'undefined') {
return WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
return MozWebSocket;
} else {
alert('Your browser does not have WebSocket support.' +
'Please try Chrome, Safari or Firefox ≥ 6. ' +
'Firefox 4 and 5 are also supported but you ' +
'have to enable WebSockets in about:config.');
};
}

mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
this.id = figure_id;

this.ws = websocket;

this.supports_binary = (this.ws.binaryType != undefined);

if (!this.supports_binary) {
var warnings = document.getElementById("mpl-warnings");
if (warnings) {
warnings.style.display = 'block';
warnings.textContent = (
"This browser does not support binary websocket messages. " +
"Performance may be slow.");
}
}

this.imageObj = new Image();

this.context = undefined;
this.message = undefined;
this.canvas = undefined;
this.rubberband_canvas = undefined;
this.rubberband_context = undefined;
this.format_dropdown = undefined;

this.image_mode = 'full';

this.root = $('<div/>'); this._root_extra_style(this.root) this.root.attr('style', 'display: inline-block');$(parent_element).append(this.root);

this._init_canvas(this);
this._init_toolbar(this);

var fig = this;

this.waiting = false;

this.ws.onopen =  function () {
fig.send_message("supports_binary", {value: fig.supports_binary});
fig.send_message("send_image_mode", {});
if (mpl.ratio != 1) {
fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
}
fig.send_message("refresh", {});
}

this.imageObj.onload = function() {
if (fig.image_mode == 'full') {
// Full images could contain transparency (where diff images
// almost always do), so we need to clear the canvas so that
// there is no ghosting.
fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
}
fig.context.drawImage(fig.imageObj, 0, 0);
};

this.imageObj.onunload = function() {
fig.ws.close();
}

this.ws.onmessage = this._make_on_message_function(this);

}

mpl.figure.prototype._init_header = function() {
var titlebar = $( '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + 'ui-helper-clearfix"/>'); var titletext =$(
'<div class="ui-dialog-title" style="width: 100%; ' +
'text-align: center; padding: 3px;"/>');
titlebar.append(titletext)
this.root.append(titlebar);
}

mpl.figure.prototype._canvas_extra_style = function(canvas_div) {

}

mpl.figure.prototype._root_extra_style = function(canvas_div) {

}

mpl.figure.prototype._init_canvas = function() {
var fig = this;

var canvas_div = $('<div/>'); canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); function canvas_keyboard_event(event) { return fig.key_event(event, event['data']); } canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); this.canvas_div = canvas_div this._canvas_extra_style(canvas_div) this.root.append(canvas_div); var canvas =$('<canvas/>');
canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")

this.canvas = canvas[0];
this.context = canvas[0].getContext("2d");

var backingStore = this.context.backingStorePixelRatio ||
this.context.webkitBackingStorePixelRatio ||
this.context.mozBackingStorePixelRatio ||
this.context.msBackingStorePixelRatio ||
this.context.oBackingStorePixelRatio ||
this.context.backingStorePixelRatio || 1;

mpl.ratio = (window.devicePixelRatio || 1) / backingStore;

var rubberband = $('<canvas/>'); rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") var pass_mouse_events = true; canvas_div.resizable({ start: function(event, ui) { pass_mouse_events = false; }, resize: function(event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, stop: function(event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { if (pass_mouse_events) return fig.mouse_event(event, event['data']); } rubberband.mousedown('button_press', mouse_event_fn); rubberband.mouseup('button_release', mouse_event_fn); // Throttle sequential mouse events to 1 every 20ms. rubberband.mousemove('motion_notify', mouse_event_fn); rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); canvas_div.on("wheel", function (event) { event = event.originalEvent; event['data'] = 'scroll' if (event.deltaY < 0) { event.step = 1; } else { event.step = -1; } mouse_event_fn(event); }); canvas_div.append(canvas); canvas_div.append(rubberband); this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; this.rubberband_context = rubberband[0].getContext("2d"); this.rubberband_context.strokeStyle = "#000000"; this._resize_canvas = function(width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. canvas_div.css('width', width) canvas_div.css('height', height) canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); rubberband.attr('width', width); rubberband.attr('height', height); } // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu.$(this.rubberband_canvas).bind("contextmenu",function(e){
return false;
});

function set_focus () {
canvas.focus();
canvas_div.focus();
}

window.setTimeout(set_focus, 100);
}

mpl.figure.prototype._init_toolbar = function() {
var fig = this;

var nav_element = $('<div/>') nav_element.attr('style', 'width: 100%'); this.root.append(nav_element); // Define a callback function for later on. function toolbar_event(event) { return fig.toolbar_button_onclick(event['data']); } function toolbar_mouse_event(event) { return fig.toolbar_button_onmouseover(event['data']); } for(var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; var method_name = mpl.toolbar_items[toolbar_ind][3]; if (!name) { // put a spacer in here. continue; } var button =$('<button/>');
button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
'ui-button-icon-only');
button.attr('role', 'button');
button.attr('aria-disabled', 'false');
button.click(method_name, toolbar_event);
button.mouseover(tooltip, toolbar_mouse_event);

var icon_img = $('<span/>'); icon_img.addClass('ui-button-icon-primary ui-icon'); icon_img.addClass(image); icon_img.addClass('ui-corner-all'); var tooltip_span =$('<span/>');
tooltip_span.html(tooltip);

button.append(icon_img);
button.append(tooltip_span);

nav_element.append(button);
}

var fmt_picker_span = $('<span/>'); var fmt_picker =$('<select/>');
fmt_picker_span.append(fmt_picker);
nav_element.append(fmt_picker_span);
this.format_dropdown = fmt_picker[0];

for (var ind in mpl.extensions) {
var fmt = mpl.extensions[ind];
var option = $( '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); fmt_picker.append(option) } // Add hover states to the ui-buttons$( ".ui-button" ).hover(
function() { $(this).addClass("ui-state-hover");}, function() {$(this).removeClass("ui-state-hover");}
);

var status_bar = $('<span class="mpl-message"/>'); nav_element.append(status_bar); this.message = status_bar[0]; } mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); } mpl.figure.prototype.send_message = function(type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); } mpl.figure.prototype.send_draw_message = function() { if (!this.waiting) { this.waiting = true; this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); } } mpl.figure.prototype.handle_save = function(fig, msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); } mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { fig._resize_canvas(size[0], size[1]); fig.send_message("refresh", {}); }; } mpl.figure.prototype.handle_rubberband = function(fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; x0 = Math.floor(x0) + 0.5; y0 = Math.floor(y0) + 0.5; x1 = Math.floor(x1) + 0.5; y1 = Math.floor(y1) + 0.5; var min_x = Math.min(x0, x1); var min_y = Math.min(y0, y1); var width = Math.abs(x1 - x0); var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( 0, 0, fig.canvas.width, fig.canvas.height); fig.rubberband_context.strokeRect(min_x, min_y, width, height); } mpl.figure.prototype.handle_figure_label = function(fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; } mpl.figure.prototype.handle_cursor = function(fig, msg) { var cursor = msg['cursor']; switch(cursor) { case 0: cursor = 'pointer'; break; case 1: cursor = 'default'; break; case 2: cursor = 'crosshair'; break; case 3: cursor = 'move'; break; } fig.rubberband_canvas.style.cursor = cursor; } mpl.figure.prototype.handle_message = function(fig, msg) { fig.message.textContent = msg['message']; } mpl.figure.prototype.handle_draw = function(fig, msg) { // Request the server to send over a new figure. fig.send_draw_message(); } mpl.figure.prototype.handle_image_mode = function(fig, msg) { fig.image_mode = msg['mode']; } mpl.figure.prototype.updated_canvas_event = function() { // Called whenever the canvas gets updated. this.send_message("ack", {}); } // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. mpl.figure.prototype._make_on_message_function = function(fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ evt.data.type = "image/png"; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( fig.imageObj.src); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( evt.data); fig.updated_canvas_event(); fig.waiting = false; return; } else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; return; } var msg = JSON.parse(evt.data); var msg_type = msg['type']; // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { var callback = fig["handle_" + msg_type]; } catch (e) { console.log("No handler for the '" + msg_type + "' message type: ", msg); return; } if (callback) { try { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); } } }; } // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas mpl.findpos = function(e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; if (!e) e = window.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) // defeat Safari bug targ = targ.parentNode; // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document // offset() returns the position of the element relative to the document var x = e.pageX -$(targ).offset().left;
var y = e.pageY - $(targ).offset().top; return {"x": x, "y": y}; }; /* * return a copy of an object with only non-object keys * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { if (typeof original[key] !== 'object') obj[key] = original[key] return obj; }, {}); } mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; this.send_message(name, {x: x, y: y, button: event.button, step: event.step, guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want * to control all of the cursor setting manually through the * 'cursor' event from matplotlib */ event.preventDefault(); return false; } mpl.figure.prototype._key_event_extra = function(event, name) { // Handle any extra behaviour associated with a key event } mpl.figure.prototype.key_event = function(event, name) { // Prevent repeat events if (name == 'key_press') { if (event.which === this._key) return; else this._key = event.which; } if (name == 'key_release') this._key = null; var value = ''; if (event.ctrlKey && event.which != 17) value += "ctrl+"; if (event.altKey && event.which != 18) value += "alt+"; if (event.shiftKey && event.which != 16) value += "shift+"; value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); this.send_message(name, {key: value, guiEvent: simpleKeys(event)}); return false; } mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } }; mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { this.message.textContent = tooltip; }; 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"]]; mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"]; mpl.default_extension = "png";var comm_websocket_adapter = function(comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; ws.close = function() { comm.close() }; ws.send = function(m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. comm.on_msg(function(msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. ws.onmessage(msg['content']['data']) }); return ws; } mpl.mpl_figure_comm = function(comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. var element =$("#" + id);
var ws_proxy = comm_websocket_adapter(comm)

window.open(figure.imageObj.src);
}

var fig = new mpl.figure(id, ws_proxy,
element.get(0));

// Call onopen now - mpl needs it, as it is assuming we've passed it a real
// web socket which is closed, not our websocket->open comm proxy.
ws_proxy.onopen();

fig.parent_element = element.get(0);
fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
if (!fig.cell_info) {
console.error("Failed to find cell for figure", id, fig);
return;
}

var output_index = fig.cell_info[2]
var cell = fig.cell_info[0];

};

mpl.figure.prototype.handle_close = function(fig, msg) {
var width = fig.canvas.width/mpl.ratio
fig.root.unbind('remove')

// Update the output cell to use the data from the current canvas.
fig.push_to_output();
var dataURL = fig.canvas.toDataURL();
// Re-enable the keyboard manager in IPython - without this line, in FF,
// the notebook keyboard shortcuts fail.
IPython.keyboard_manager.enable()
$(fig.parent_element).html('<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'); fig.close_ws(fig, msg); } mpl.figure.prototype.close_ws = function(fig, msg){ fig.send_message('closing', msg); // fig.ws.close() } mpl.figure.prototype.push_to_output = function(remove_interactive) { // Turn the data on the canvas into data in the output cell. var width = this.canvas.width/mpl.ratio var dataURL = this.canvas.toDataURL(); this.cell_info[1]['text/html'] = '<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'; } mpl.figure.prototype.updated_canvas_event = function() { // Tell IPython that the notebook contents must change. IPython.notebook.set_dirty(true); this.send_message("ack", {}); var fig = this; // Wait a second, then push the new image to the DOM so // that it is saved nicely (might be nice to debounce this). setTimeout(function () { fig.push_to_output() }, 1000); } mpl.figure.prototype._init_toolbar = function() { var fig = this; var nav_element =$('<div/>')
nav_element.attr('style', 'width: 100%');
this.root.append(nav_element);

// Define a callback function for later on.
function toolbar_event(event) {
return fig.toolbar_button_onclick(event['data']);
}
function toolbar_mouse_event(event) {
return fig.toolbar_button_onmouseover(event['data']);
}

for(var toolbar_ind in mpl.toolbar_items){
var name = mpl.toolbar_items[toolbar_ind][0];
var tooltip = mpl.toolbar_items[toolbar_ind][1];
var image = mpl.toolbar_items[toolbar_ind][2];
var method_name = mpl.toolbar_items[toolbar_ind][3];

if (!name) { continue; };

var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); button.click(method_name, toolbar_event); button.mouseover(tooltip, toolbar_mouse_event); nav_element.append(button); } // Add the status bar. var status_bar =$('<span class="mpl-message" style="text-align:right; float: right;"/>');
nav_element.append(status_bar);
this.message = status_bar[0];

// Add the close button to the window.
var buttongrp = $('<div class="btn-group inline pull-right"></div>'); 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>');
button.click(function (evt) { fig.handle_close(fig, {}); } );
button.mouseover('Stop Interaction', toolbar_mouse_event);
buttongrp.append(button);
var titlebar = this.root.find($('.ui-dialog-titlebar')); titlebar.prepend(buttongrp); } mpl.figure.prototype._root_extra_style = function(el){ var fig = this el.on("remove", function(){ fig.close_ws(fig, {}); }); } mpl.figure.prototype._canvas_extra_style = function(el){ // this is important to make the div 'focusable el.attr('tabindex', 0) // reach out to IPython and tell the keyboard manager to turn it's self // off when our div gets focus // location in version 3 if (IPython.notebook.keyboard_manager) { IPython.notebook.keyboard_manager.register_events(el); } else { // location in version 2 IPython.keyboard_manager.register_events(el); } } mpl.figure.prototype._key_event_extra = function(event, name) { var manager = IPython.notebook.keyboard_manager; if (!manager) manager = IPython.keyboard_manager; // Check for shift+enter if (event.shiftKey && event.which == 13) { this.canvas_div.blur(); event.shiftKey = false; // Send a "J" for go to next cell event.which = 74; event.keyCode = 74; manager.command_mode(); manager.handle_keydown(event); } } mpl.figure.prototype.handle_save = function(fig, msg) { fig.ondownload(fig, null); } mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" // IPython event is triggered only after the cells have been serialised, which for // our purposes (turning an active figure into a static one), is too late. var cells = IPython.notebook.get_cells(); var ncells = cells.length; for (var i=0; i<ncells; i++) { var cell = cells[i]; if (cell.cell_type === 'code'){ for (var j=0; j<cell.output_area.outputs.length; j++) { var data = cell.output_area.outputs[j]; if (data.data) { // IPython >= 3 moved mimebundle to data attribute of output data = data.data; } if (data['text/html'] == html_output) { return [cell, data, j]; } } } } } // Register the function which deals with the matplotlib target/channel. // The kernel may be null if the page has been refreshed. if (IPython.notebook.kernel != null) { IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); }  ## Fast Fourier Transform (FFT) ### Spectrogram Let's compute the spectrogram for an audio file. We will pick an arpeggio in guitar.  In [18]: from scipy.io import wavfile   In [19]: rate, signal = wavfile.read("nst_arpeggios_c_audio.wav") nsamples = signal.shape[0] time = np.linspace(0, nsamples/rate, nsamples)   In [20]: # Create figure fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 2.5)) fig.tight_layout() # Time plot #ax1.set_figure(figsize=(3.5, 2.5)) ax1.plot(time, signal[:, 0]/1000, color="#e41a1c") ax1.set_title('Raw audio signal') ax1.set_xlim(0, 20) ax1.set_xlabel("Time [s]") ax1.set_ylabel("Amplitude") # Spectrogram Pxx, freqs, bins, im = ax2.specgram(signal[:, 0], Fs=rate, cmap="magma") ax2.set_ylim([0, max(freqs)]) ax1.set_xlabel("Time [s]") ax2.set_ylabel("Frequency [kHz]") ax2.set_title('Spectrogram'); bound = np.linspace(-40, 40, 51) cb = fig.colorbar(im, boundaries=bound, ticks=bound[::10]) cb.set_label('Intensity [dB]') cb.set_clim(-40, 40) # Rescale y-axis scale = 1e3 # KHz ticks = matplotlib.ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale)) ax2.yaxis.set_major_formatter(ticks) plt.tight_layout();   var element =$('#2475e1bc-ef21-41c9-b547-bdfa638f4750');
/* Put everything inside the global mpl namespace */
window.mpl = {};

mpl.get_websocket_type = function() {
if (typeof(WebSocket) !== 'undefined') {
return WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
return MozWebSocket;
} else {
alert('Your browser does not have WebSocket support.' +
'Please try Chrome, Safari or Firefox ≥ 6. ' +
'Firefox 4 and 5 are also supported but you ' +
'have to enable WebSockets in about:config.');
};
}

mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
this.id = figure_id;

this.ws = websocket;

this.supports_binary = (this.ws.binaryType != undefined);

if (!this.supports_binary) {
var warnings = document.getElementById("mpl-warnings");
if (warnings) {
warnings.style.display = 'block';
warnings.textContent = (
"This browser does not support binary websocket messages. " +
"Performance may be slow.");
}
}

this.imageObj = new Image();

this.context = undefined;
this.message = undefined;
this.canvas = undefined;
this.rubberband_canvas = undefined;
this.rubberband_context = undefined;
this.format_dropdown = undefined;

this.image_mode = 'full';

this.root = $('<div/>'); this._root_extra_style(this.root) this.root.attr('style', 'display: inline-block');$(parent_element).append(this.root);

this._init_canvas(this);
this._init_toolbar(this);

var fig = this;

this.waiting = false;

this.ws.onopen =  function () {
fig.send_message("supports_binary", {value: fig.supports_binary});
fig.send_message("send_image_mode", {});
if (mpl.ratio != 1) {
fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
}
fig.send_message("refresh", {});
}

this.imageObj.onload = function() {
if (fig.image_mode == 'full') {
// Full images could contain transparency (where diff images
// almost always do), so we need to clear the canvas so that
// there is no ghosting.
fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
}
fig.context.drawImage(fig.imageObj, 0, 0);
};

this.imageObj.onunload = function() {
fig.ws.close();
}

this.ws.onmessage = this._make_on_message_function(this);

}

mpl.figure.prototype._init_header = function() {
var titlebar = $( '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + 'ui-helper-clearfix"/>'); var titletext =$(
'<div class="ui-dialog-title" style="width: 100%; ' +
'text-align: center; padding: 3px;"/>');
titlebar.append(titletext)
this.root.append(titlebar);
}

mpl.figure.prototype._canvas_extra_style = function(canvas_div) {

}

mpl.figure.prototype._root_extra_style = function(canvas_div) {

}

mpl.figure.prototype._init_canvas = function() {
var fig = this;

var canvas_div = $('<div/>'); canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); function canvas_keyboard_event(event) { return fig.key_event(event, event['data']); } canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); this.canvas_div = canvas_div this._canvas_extra_style(canvas_div) this.root.append(canvas_div); var canvas =$('<canvas/>');
canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")

this.canvas = canvas[0];
this.context = canvas[0].getContext("2d");

var backingStore = this.context.backingStorePixelRatio ||
this.context.webkitBackingStorePixelRatio ||
this.context.mozBackingStorePixelRatio ||
this.context.msBackingStorePixelRatio ||
this.context.oBackingStorePixelRatio ||
this.context.backingStorePixelRatio || 1;

mpl.ratio = (window.devicePixelRatio || 1) / backingStore;

var rubberband = $('<canvas/>'); rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") var pass_mouse_events = true; canvas_div.resizable({ start: function(event, ui) { pass_mouse_events = false; }, resize: function(event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, stop: function(event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { if (pass_mouse_events) return fig.mouse_event(event, event['data']); } rubberband.mousedown('button_press', mouse_event_fn); rubberband.mouseup('button_release', mouse_event_fn); // Throttle sequential mouse events to 1 every 20ms. rubberband.mousemove('motion_notify', mouse_event_fn); rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); canvas_div.on("wheel", function (event) { event = event.originalEvent; event['data'] = 'scroll' if (event.deltaY < 0) { event.step = 1; } else { event.step = -1; } mouse_event_fn(event); }); canvas_div.append(canvas); canvas_div.append(rubberband); this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; this.rubberband_context = rubberband[0].getContext("2d"); this.rubberband_context.strokeStyle = "#000000"; this._resize_canvas = function(width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. canvas_div.css('width', width) canvas_div.css('height', height) canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); rubberband.attr('width', width); rubberband.attr('height', height); } // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu.$(this.rubberband_canvas).bind("contextmenu",function(e){
return false;
});

function set_focus () {
canvas.focus();
canvas_div.focus();
}

window.setTimeout(set_focus, 100);
}

mpl.figure.prototype._init_toolbar = function() {
var fig = this;

var nav_element = $('<div/>') nav_element.attr('style', 'width: 100%'); this.root.append(nav_element); // Define a callback function for later on. function toolbar_event(event) { return fig.toolbar_button_onclick(event['data']); } function toolbar_mouse_event(event) { return fig.toolbar_button_onmouseover(event['data']); } for(var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; var method_name = mpl.toolbar_items[toolbar_ind][3]; if (!name) { // put a spacer in here. continue; } var button =$('<button/>');
button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
'ui-button-icon-only');
button.attr('role', 'button');
button.attr('aria-disabled', 'false');
button.click(method_name, toolbar_event);
button.mouseover(tooltip, toolbar_mouse_event);

var icon_img = $('<span/>'); icon_img.addClass('ui-button-icon-primary ui-icon'); icon_img.addClass(image); icon_img.addClass('ui-corner-all'); var tooltip_span =$('<span/>');
tooltip_span.html(tooltip);

button.append(icon_img);
button.append(tooltip_span);

nav_element.append(button);
}

var fmt_picker_span = $('<span/>'); var fmt_picker =$('<select/>');
fmt_picker_span.append(fmt_picker);
nav_element.append(fmt_picker_span);
this.format_dropdown = fmt_picker[0];

for (var ind in mpl.extensions) {
var fmt = mpl.extensions[ind];
var option = $( '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); fmt_picker.append(option) } // Add hover states to the ui-buttons$( ".ui-button" ).hover(
function() { $(this).addClass("ui-state-hover");}, function() {$(this).removeClass("ui-state-hover");}
);

var status_bar = $('<span class="mpl-message"/>'); nav_element.append(status_bar); this.message = status_bar[0]; } mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); } mpl.figure.prototype.send_message = function(type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); } mpl.figure.prototype.send_draw_message = function() { if (!this.waiting) { this.waiting = true; this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); } } mpl.figure.prototype.handle_save = function(fig, msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); } mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { fig._resize_canvas(size[0], size[1]); fig.send_message("refresh", {}); }; } mpl.figure.prototype.handle_rubberband = function(fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; x0 = Math.floor(x0) + 0.5; y0 = Math.floor(y0) + 0.5; x1 = Math.floor(x1) + 0.5; y1 = Math.floor(y1) + 0.5; var min_x = Math.min(x0, x1); var min_y = Math.min(y0, y1); var width = Math.abs(x1 - x0); var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( 0, 0, fig.canvas.width, fig.canvas.height); fig.rubberband_context.strokeRect(min_x, min_y, width, height); } mpl.figure.prototype.handle_figure_label = function(fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; } mpl.figure.prototype.handle_cursor = function(fig, msg) { var cursor = msg['cursor']; switch(cursor) { case 0: cursor = 'pointer'; break; case 1: cursor = 'default'; break; case 2: cursor = 'crosshair'; break; case 3: cursor = 'move'; break; } fig.rubberband_canvas.style.cursor = cursor; } mpl.figure.prototype.handle_message = function(fig, msg) { fig.message.textContent = msg['message']; } mpl.figure.prototype.handle_draw = function(fig, msg) { // Request the server to send over a new figure. fig.send_draw_message(); } mpl.figure.prototype.handle_image_mode = function(fig, msg) { fig.image_mode = msg['mode']; } mpl.figure.prototype.updated_canvas_event = function() { // Called whenever the canvas gets updated. this.send_message("ack", {}); } // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. mpl.figure.prototype._make_on_message_function = function(fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ evt.data.type = "image/png"; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( fig.imageObj.src); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( evt.data); fig.updated_canvas_event(); fig.waiting = false; return; } else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; return; } var msg = JSON.parse(evt.data); var msg_type = msg['type']; // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { var callback = fig["handle_" + msg_type]; } catch (e) { console.log("No handler for the '" + msg_type + "' message type: ", msg); return; } if (callback) { try { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); } } }; } // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas mpl.findpos = function(e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; if (!e) e = window.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) // defeat Safari bug targ = targ.parentNode; // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document // offset() returns the position of the element relative to the document var x = e.pageX -$(targ).offset().left;
var y = e.pageY - $(targ).offset().top; return {"x": x, "y": y}; }; /* * return a copy of an object with only non-object keys * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { if (typeof original[key] !== 'object') obj[key] = original[key] return obj; }, {}); } mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; this.send_message(name, {x: x, y: y, button: event.button, step: event.step, guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want * to control all of the cursor setting manually through the * 'cursor' event from matplotlib */ event.preventDefault(); return false; } mpl.figure.prototype._key_event_extra = function(event, name) { // Handle any extra behaviour associated with a key event } mpl.figure.prototype.key_event = function(event, name) { // Prevent repeat events if (name == 'key_press') { if (event.which === this._key) return; else this._key = event.which; } if (name == 'key_release') this._key = null; var value = ''; if (event.ctrlKey && event.which != 17) value += "ctrl+"; if (event.altKey && event.which != 18) value += "alt+"; if (event.shiftKey && event.which != 16) value += "shift+"; value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); this.send_message(name, {key: value, guiEvent: simpleKeys(event)}); return false; } mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } }; mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { this.message.textContent = tooltip; }; 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"]]; mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"]; mpl.default_extension = "png";var comm_websocket_adapter = function(comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; ws.close = function() { comm.close() }; ws.send = function(m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. comm.on_msg(function(msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. ws.onmessage(msg['content']['data']) }); return ws; } mpl.mpl_figure_comm = function(comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. var element =$("#" + id);
var ws_proxy = comm_websocket_adapter(comm)

window.open(figure.imageObj.src);
}

var fig = new mpl.figure(id, ws_proxy,
element.get(0));

// Call onopen now - mpl needs it, as it is assuming we've passed it a real
// web socket which is closed, not our websocket->open comm proxy.
ws_proxy.onopen();

fig.parent_element = element.get(0);
fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
if (!fig.cell_info) {
console.error("Failed to find cell for figure", id, fig);
return;
}

var output_index = fig.cell_info[2]
var cell = fig.cell_info[0];

};

mpl.figure.prototype.handle_close = function(fig, msg) {
var width = fig.canvas.width/mpl.ratio
fig.root.unbind('remove')

// Update the output cell to use the data from the current canvas.
fig.push_to_output();
var dataURL = fig.canvas.toDataURL();
// Re-enable the keyboard manager in IPython - without this line, in FF,
// the notebook keyboard shortcuts fail.
IPython.keyboard_manager.enable()
$(fig.parent_element).html('<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'); fig.close_ws(fig, msg); } mpl.figure.prototype.close_ws = function(fig, msg){ fig.send_message('closing', msg); // fig.ws.close() } mpl.figure.prototype.push_to_output = function(remove_interactive) { // Turn the data on the canvas into data in the output cell. var width = this.canvas.width/mpl.ratio var dataURL = this.canvas.toDataURL(); this.cell_info[1]['text/html'] = '<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'; } mpl.figure.prototype.updated_canvas_event = function() { // Tell IPython that the notebook contents must change. IPython.notebook.set_dirty(true); this.send_message("ack", {}); var fig = this; // Wait a second, then push the new image to the DOM so // that it is saved nicely (might be nice to debounce this). setTimeout(function () { fig.push_to_output() }, 1000); } mpl.figure.prototype._init_toolbar = function() { var fig = this; var nav_element =$('<div/>')
nav_element.attr('style', 'width: 100%');
this.root.append(nav_element);

// Define a callback function for later on.
function toolbar_event(event) {
return fig.toolbar_button_onclick(event['data']);
}
function toolbar_mouse_event(event) {
return fig.toolbar_button_onmouseover(event['data']);
}

for(var toolbar_ind in mpl.toolbar_items){
var name = mpl.toolbar_items[toolbar_ind][0];
var tooltip = mpl.toolbar_items[toolbar_ind][1];
var image = mpl.toolbar_items[toolbar_ind][2];
var method_name = mpl.toolbar_items[toolbar_ind][3];

if (!name) { continue; };

var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); button.click(method_name, toolbar_event); button.mouseover(tooltip, toolbar_mouse_event); nav_element.append(button); } // Add the status bar. var status_bar =$('<span class="mpl-message" style="text-align:right; float: right;"/>');
nav_element.append(status_bar);
this.message = status_bar[0];

// Add the close button to the window.
var buttongrp = $('<div class="btn-group inline pull-right"></div>'); 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>');
button.click(function (evt) { fig.handle_close(fig, {}); } );
button.mouseover('Stop Interaction', toolbar_mouse_event);
buttongrp.append(button);
var titlebar = this.root.find($('.ui-dialog-titlebar')); titlebar.prepend(buttongrp); } mpl.figure.prototype._root_extra_style = function(el){ var fig = this el.on("remove", function(){ fig.close_ws(fig, {}); }); } mpl.figure.prototype._canvas_extra_style = function(el){ // this is important to make the div 'focusable el.attr('tabindex', 0) // reach out to IPython and tell the keyboard manager to turn it's self // off when our div gets focus // location in version 3 if (IPython.notebook.keyboard_manager) { IPython.notebook.keyboard_manager.register_events(el); } else { // location in version 2 IPython.keyboard_manager.register_events(el); } } mpl.figure.prototype._key_event_extra = function(event, name) { var manager = IPython.notebook.keyboard_manager; if (!manager) manager = IPython.keyboard_manager; // Check for shift+enter if (event.shiftKey && event.which == 13) { this.canvas_div.blur(); event.shiftKey = false; // Send a "J" for go to next cell event.which = 74; event.keyCode = 74; manager.command_mode(); manager.handle_keydown(event); } } mpl.figure.prototype.handle_save = function(fig, msg) { fig.ondownload(fig, null); } mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" // IPython event is triggered only after the cells have been serialised, which for // our purposes (turning an active figure into a static one), is too late. var cells = IPython.notebook.get_cells(); var ncells = cells.length; for (var i=0; i<ncells; i++) { var cell = cells[i]; if (cell.cell_type === 'code'){ for (var j=0; j<cell.output_area.outputs.length; j++) { var data = cell.output_area.outputs[j]; if (data.data) { // IPython >= 3 moved mimebundle to data attribute of output data = data.data; } if (data['text/html'] == html_output) { return [cell, data, j]; } } } } } // Register the function which deals with the matplotlib target/channel. // The kernel may be null if the page has been refreshed. if (IPython.notebook.kernel != null) { IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); } /home/nguarinz/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py:7609: RuntimeWarning: divide by zero encountered in log10 Z = 10. * np.log10(spec)  ### FFT using scipy.fftpack This section is copied from Scipy Lecture Notes. The scipy.fftpack module allows to compute fast Fourier transforms. As an illustration, a (noisy) input signal may look like:  In [21]: time_step = 0.02 period = 5. time_vec = np.arange(0, 20, time_step) sig = np.sin(2 * np.pi / period * time_vec) + \ 0.5 * np.random.randn(time_vec.size)  The observer doesn’t know the signal frequency, only the sampling time step of the signal sig. The signal is supposed to come from a real function so the Fourier transform will be symmetric. The scipy.fftpack.fftfreq() function will generate the sampling frequencies and scipy.fftpack.fft() will compute the fast Fourier transform:  In [22]: from scipy import fftpack sample_freq = fftpack.fftfreq(sig.size, d=time_step) sig_fft = fftpack.fft(sig)  Because the resulting power is symmetric, only the positive part of the spectrum needs to be used for finding the frequency:  In [23]: pidxs = np.where(sample_freq > 0) freqs = sample_freq[pidxs] power = np.abs(sig_fft)[pidxs]   In [24]: plt.figure() plt.plot(freqs, power, color="#e41a1c") plt.xlabel('Frequency [Hz]') plt.ylabel('plower') axes = plt.axes([0.3, 0.3, 0.5, 0.5]) plt.title('Peak frequency') plt.plot(freqs[:8], power[:8], color="#e41a1c") plt.setp(axes, yticks=[]);   var element =$('#ccfcc643-4db3-44c9-b49f-4853300a36b9');
/* Put everything inside the global mpl namespace */
window.mpl = {};

mpl.get_websocket_type = function() {
if (typeof(WebSocket) !== 'undefined') {
return WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
return MozWebSocket;
} else {
alert('Your browser does not have WebSocket support.' +
'Please try Chrome, Safari or Firefox ≥ 6. ' +
'Firefox 4 and 5 are also supported but you ' +
'have to enable WebSockets in about:config.');
};
}

mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
this.id = figure_id;

this.ws = websocket;

this.supports_binary = (this.ws.binaryType != undefined);

if (!this.supports_binary) {
var warnings = document.getElementById("mpl-warnings");
if (warnings) {
warnings.style.display = 'block';
warnings.textContent = (
"This browser does not support binary websocket messages. " +
"Performance may be slow.");
}
}

this.imageObj = new Image();

this.context = undefined;
this.message = undefined;
this.canvas = undefined;
this.rubberband_canvas = undefined;
this.rubberband_context = undefined;
this.format_dropdown = undefined;

this.image_mode = 'full';

this.root = $('<div/>'); this._root_extra_style(this.root) this.root.attr('style', 'display: inline-block');$(parent_element).append(this.root);

this._init_canvas(this);
this._init_toolbar(this);

var fig = this;

this.waiting = false;

this.ws.onopen =  function () {
fig.send_message("supports_binary", {value: fig.supports_binary});
fig.send_message("send_image_mode", {});
if (mpl.ratio != 1) {
fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
}
fig.send_message("refresh", {});
}

this.imageObj.onload = function() {
if (fig.image_mode == 'full') {
// Full images could contain transparency (where diff images
// almost always do), so we need to clear the canvas so that
// there is no ghosting.
fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
}
fig.context.drawImage(fig.imageObj, 0, 0);
};

this.imageObj.onunload = function() {
fig.ws.close();
}

this.ws.onmessage = this._make_on_message_function(this);

}

mpl.figure.prototype._init_header = function() {
var titlebar = $( '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + 'ui-helper-clearfix"/>'); var titletext =$(
'<div class="ui-dialog-title" style="width: 100%; ' +
'text-align: center; padding: 3px;"/>');
titlebar.append(titletext)
this.root.append(titlebar);
}

mpl.figure.prototype._canvas_extra_style = function(canvas_div) {

}

mpl.figure.prototype._root_extra_style = function(canvas_div) {

}

mpl.figure.prototype._init_canvas = function() {
var fig = this;

var canvas_div = $('<div/>'); canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); function canvas_keyboard_event(event) { return fig.key_event(event, event['data']); } canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); this.canvas_div = canvas_div this._canvas_extra_style(canvas_div) this.root.append(canvas_div); var canvas =$('<canvas/>');
canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")

this.canvas = canvas[0];
this.context = canvas[0].getContext("2d");

var backingStore = this.context.backingStorePixelRatio ||
this.context.webkitBackingStorePixelRatio ||
this.context.mozBackingStorePixelRatio ||
this.context.msBackingStorePixelRatio ||
this.context.oBackingStorePixelRatio ||
this.context.backingStorePixelRatio || 1;

mpl.ratio = (window.devicePixelRatio || 1) / backingStore;

var rubberband = $('<canvas/>'); rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") var pass_mouse_events = true; canvas_div.resizable({ start: function(event, ui) { pass_mouse_events = false; }, resize: function(event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, stop: function(event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { if (pass_mouse_events) return fig.mouse_event(event, event['data']); } rubberband.mousedown('button_press', mouse_event_fn); rubberband.mouseup('button_release', mouse_event_fn); // Throttle sequential mouse events to 1 every 20ms. rubberband.mousemove('motion_notify', mouse_event_fn); rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); canvas_div.on("wheel", function (event) { event = event.originalEvent; event['data'] = 'scroll' if (event.deltaY < 0) { event.step = 1; } else { event.step = -1; } mouse_event_fn(event); }); canvas_div.append(canvas); canvas_div.append(rubberband); this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; this.rubberband_context = rubberband[0].getContext("2d"); this.rubberband_context.strokeStyle = "#000000"; this._resize_canvas = function(width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. canvas_div.css('width', width) canvas_div.css('height', height) canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); rubberband.attr('width', width); rubberband.attr('height', height); } // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu.$(this.rubberband_canvas).bind("contextmenu",function(e){
return false;
});

function set_focus () {
canvas.focus();
canvas_div.focus();
}

window.setTimeout(set_focus, 100);
}

mpl.figure.prototype._init_toolbar = function() {
var fig = this;

var nav_element = $('<div/>') nav_element.attr('style', 'width: 100%'); this.root.append(nav_element); // Define a callback function for later on. function toolbar_event(event) { return fig.toolbar_button_onclick(event['data']); } function toolbar_mouse_event(event) { return fig.toolbar_button_onmouseover(event['data']); } for(var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; var method_name = mpl.toolbar_items[toolbar_ind][3]; if (!name) { // put a spacer in here. continue; } var button =$('<button/>');
button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
'ui-button-icon-only');
button.attr('role', 'button');
button.attr('aria-disabled', 'false');
button.click(method_name, toolbar_event);
button.mouseover(tooltip, toolbar_mouse_event);

var icon_img = $('<span/>'); icon_img.addClass('ui-button-icon-primary ui-icon'); icon_img.addClass(image); icon_img.addClass('ui-corner-all'); var tooltip_span =$('<span/>');
tooltip_span.html(tooltip);

button.append(icon_img);
button.append(tooltip_span);

nav_element.append(button);
}

var fmt_picker_span = $('<span/>'); var fmt_picker =$('<select/>');
fmt_picker_span.append(fmt_picker);
nav_element.append(fmt_picker_span);
this.format_dropdown = fmt_picker[0];

for (var ind in mpl.extensions) {
var fmt = mpl.extensions[ind];
var option = $( '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); fmt_picker.append(option) } // Add hover states to the ui-buttons$( ".ui-button" ).hover(
function() { $(this).addClass("ui-state-hover");}, function() {$(this).removeClass("ui-state-hover");}
);

var status_bar = $('<span class="mpl-message"/>'); nav_element.append(status_bar); this.message = status_bar[0]; } mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); } mpl.figure.prototype.send_message = function(type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); } mpl.figure.prototype.send_draw_message = function() { if (!this.waiting) { this.waiting = true; this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); } } mpl.figure.prototype.handle_save = function(fig, msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); } mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { fig._resize_canvas(size[0], size[1]); fig.send_message("refresh", {}); }; } mpl.figure.prototype.handle_rubberband = function(fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; x0 = Math.floor(x0) + 0.5; y0 = Math.floor(y0) + 0.5; x1 = Math.floor(x1) + 0.5; y1 = Math.floor(y1) + 0.5; var min_x = Math.min(x0, x1); var min_y = Math.min(y0, y1); var width = Math.abs(x1 - x0); var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( 0, 0, fig.canvas.width, fig.canvas.height); fig.rubberband_context.strokeRect(min_x, min_y, width, height); } mpl.figure.prototype.handle_figure_label = function(fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; } mpl.figure.prototype.handle_cursor = function(fig, msg) { var cursor = msg['cursor']; switch(cursor) { case 0: cursor = 'pointer'; break; case 1: cursor = 'default'; break; case 2: cursor = 'crosshair'; break; case 3: cursor = 'move'; break; } fig.rubberband_canvas.style.cursor = cursor; } mpl.figure.prototype.handle_message = function(fig, msg) { fig.message.textContent = msg['message']; } mpl.figure.prototype.handle_draw = function(fig, msg) { // Request the server to send over a new figure. fig.send_draw_message(); } mpl.figure.prototype.handle_image_mode = function(fig, msg) { fig.image_mode = msg['mode']; } mpl.figure.prototype.updated_canvas_event = function() { // Called whenever the canvas gets updated. this.send_message("ack", {}); } // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. mpl.figure.prototype._make_on_message_function = function(fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ evt.data.type = "image/png"; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( fig.imageObj.src); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( evt.data); fig.updated_canvas_event(); fig.waiting = false; return; } else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; return; } var msg = JSON.parse(evt.data); var msg_type = msg['type']; // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { var callback = fig["handle_" + msg_type]; } catch (e) { console.log("No handler for the '" + msg_type + "' message type: ", msg); return; } if (callback) { try { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); } } }; } // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas mpl.findpos = function(e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; if (!e) e = window.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) // defeat Safari bug targ = targ.parentNode; // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document // offset() returns the position of the element relative to the document var x = e.pageX -$(targ).offset().left;
var y = e.pageY - $(targ).offset().top; return {"x": x, "y": y}; }; /* * return a copy of an object with only non-object keys * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { if (typeof original[key] !== 'object') obj[key] = original[key] return obj; }, {}); } mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; this.send_message(name, {x: x, y: y, button: event.button, step: event.step, guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want * to control all of the cursor setting manually through the * 'cursor' event from matplotlib */ event.preventDefault(); return false; } mpl.figure.prototype._key_event_extra = function(event, name) { // Handle any extra behaviour associated with a key event } mpl.figure.prototype.key_event = function(event, name) { // Prevent repeat events if (name == 'key_press') { if (event.which === this._key) return; else this._key = event.which; } if (name == 'key_release') this._key = null; var value = ''; if (event.ctrlKey && event.which != 17) value += "ctrl+"; if (event.altKey && event.which != 18) value += "alt+"; if (event.shiftKey && event.which != 16) value += "shift+"; value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); this.send_message(name, {key: value, guiEvent: simpleKeys(event)}); return false; } mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } }; mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { this.message.textContent = tooltip; }; 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"]]; mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"]; mpl.default_extension = "png";var comm_websocket_adapter = function(comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; ws.close = function() { comm.close() }; ws.send = function(m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. comm.on_msg(function(msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. ws.onmessage(msg['content']['data']) }); return ws; } mpl.mpl_figure_comm = function(comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. var element =$("#" + id);
var ws_proxy = comm_websocket_adapter(comm)

window.open(figure.imageObj.src);
}

var fig = new mpl.figure(id, ws_proxy,
element.get(0));

// Call onopen now - mpl needs it, as it is assuming we've passed it a real
// web socket which is closed, not our websocket->open comm proxy.
ws_proxy.onopen();

fig.parent_element = element.get(0);
fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
if (!fig.cell_info) {
console.error("Failed to find cell for figure", id, fig);
return;
}

var output_index = fig.cell_info[2]
var cell = fig.cell_info[0];

};

mpl.figure.prototype.handle_close = function(fig, msg) {
var width = fig.canvas.width/mpl.ratio
fig.root.unbind('remove')

// Update the output cell to use the data from the current canvas.
fig.push_to_output();
var dataURL = fig.canvas.toDataURL();
// Re-enable the keyboard manager in IPython - without this line, in FF,
// the notebook keyboard shortcuts fail.
IPython.keyboard_manager.enable()
$(fig.parent_element).html('<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'); fig.close_ws(fig, msg); } mpl.figure.prototype.close_ws = function(fig, msg){ fig.send_message('closing', msg); // fig.ws.close() } mpl.figure.prototype.push_to_output = function(remove_interactive) { // Turn the data on the canvas into data in the output cell. var width = this.canvas.width/mpl.ratio var dataURL = this.canvas.toDataURL(); this.cell_info[1]['text/html'] = '<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'; } mpl.figure.prototype.updated_canvas_event = function() { // Tell IPython that the notebook contents must change. IPython.notebook.set_dirty(true); this.send_message("ack", {}); var fig = this; // Wait a second, then push the new image to the DOM so // that it is saved nicely (might be nice to debounce this). setTimeout(function () { fig.push_to_output() }, 1000); } mpl.figure.prototype._init_toolbar = function() { var fig = this; var nav_element =$('<div/>')
nav_element.attr('style', 'width: 100%');
this.root.append(nav_element);

// Define a callback function for later on.
function toolbar_event(event) {
return fig.toolbar_button_onclick(event['data']);
}
function toolbar_mouse_event(event) {
return fig.toolbar_button_onmouseover(event['data']);
}

for(var toolbar_ind in mpl.toolbar_items){
var name = mpl.toolbar_items[toolbar_ind][0];
var tooltip = mpl.toolbar_items[toolbar_ind][1];
var image = mpl.toolbar_items[toolbar_ind][2];
var method_name = mpl.toolbar_items[toolbar_ind][3];

if (!name) { continue; };

var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); button.click(method_name, toolbar_event); button.mouseover(tooltip, toolbar_mouse_event); nav_element.append(button); } // Add the status bar. var status_bar =$('<span class="mpl-message" style="text-align:right; float: right;"/>');
nav_element.append(status_bar);
this.message = status_bar[0];

// Add the close button to the window.
var buttongrp = $('<div class="btn-group inline pull-right"></div>'); 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>');
button.click(function (evt) { fig.handle_close(fig, {}); } );
button.mouseover('Stop Interaction', toolbar_mouse_event);
buttongrp.append(button);
var titlebar = this.root.find($('.ui-dialog-titlebar')); titlebar.prepend(buttongrp); } mpl.figure.prototype._root_extra_style = function(el){ var fig = this el.on("remove", function(){ fig.close_ws(fig, {}); }); } mpl.figure.prototype._canvas_extra_style = function(el){ // this is important to make the div 'focusable el.attr('tabindex', 0) // reach out to IPython and tell the keyboard manager to turn it's self // off when our div gets focus // location in version 3 if (IPython.notebook.keyboard_manager) { IPython.notebook.keyboard_manager.register_events(el); } else { // location in version 2 IPython.keyboard_manager.register_events(el); } } mpl.figure.prototype._key_event_extra = function(event, name) { var manager = IPython.notebook.keyboard_manager; if (!manager) manager = IPython.keyboard_manager; // Check for shift+enter if (event.shiftKey && event.which == 13) { this.canvas_div.blur(); event.shiftKey = false; // Send a "J" for go to next cell event.which = 74; event.keyCode = 74; manager.command_mode(); manager.handle_keydown(event); } } mpl.figure.prototype.handle_save = function(fig, msg) { fig.ondownload(fig, null); } mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" // IPython event is triggered only after the cells have been serialised, which for // our purposes (turning an active figure into a static one), is too late. var cells = IPython.notebook.get_cells(); var ncells = cells.length; for (var i=0; i<ncells; i++) { var cell = cells[i]; if (cell.cell_type === 'code'){ for (var j=0; j<cell.output_area.outputs.length; j++) { var data = cell.output_area.outputs[j]; if (data.data) { // IPython >= 3 moved mimebundle to data attribute of output data = data.data; } if (data['text/html'] == html_output) { return [cell, data, j]; } } } } } // Register the function which deals with the matplotlib target/channel. // The kernel may be null if the page has been refreshed. if (IPython.notebook.kernel != null) { IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); }  The signal frequency can be found by:  In [25]: freq = freqs[power.argmax()] np.allclose(freq, 1./period) # check that correct freq is found   Out[25]: True  Now the high-frequency noise will be removed from the Fourier transformed signal:  In [26]: sig_fft[np.abs(sample_freq) > freq] = 0  The resulting filtered signal can be computed by the scipy.fftpack.ifft() function:  In [27]: main_sig = fftpack.ifft(sig_fft)   In [28]: plt.figure() plt.plot(time_vec, sig, color="#e41a1c") plt.plot(time_vec, np.real(main_sig), linewidth=3, color="#377eb8") plt.xlabel('Time [s]') plt.ylabel('Amplitude');   var element =$('#d4c2048c-b424-4bef-9234-2c12718ed549');
/* Put everything inside the global mpl namespace */
window.mpl = {};

mpl.get_websocket_type = function() {
if (typeof(WebSocket) !== 'undefined') {
return WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
return MozWebSocket;
} else {
alert('Your browser does not have WebSocket support.' +
'Please try Chrome, Safari or Firefox ≥ 6. ' +
'Firefox 4 and 5 are also supported but you ' +
'have to enable WebSockets in about:config.');
};
}

mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
this.id = figure_id;

this.ws = websocket;

this.supports_binary = (this.ws.binaryType != undefined);

if (!this.supports_binary) {
var warnings = document.getElementById("mpl-warnings");
if (warnings) {
warnings.style.display = 'block';
warnings.textContent = (
"This browser does not support binary websocket messages. " +
"Performance may be slow.");
}
}

this.imageObj = new Image();

this.context = undefined;
this.message = undefined;
this.canvas = undefined;
this.rubberband_canvas = undefined;
this.rubberband_context = undefined;
this.format_dropdown = undefined;

this.image_mode = 'full';

this.root = $('<div/>'); this._root_extra_style(this.root) this.root.attr('style', 'display: inline-block');$(parent_element).append(this.root);

this._init_canvas(this);
this._init_toolbar(this);

var fig = this;

this.waiting = false;

this.ws.onopen =  function () {
fig.send_message("supports_binary", {value: fig.supports_binary});
fig.send_message("send_image_mode", {});
if (mpl.ratio != 1) {
fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
}
fig.send_message("refresh", {});
}

this.imageObj.onload = function() {
if (fig.image_mode == 'full') {
// Full images could contain transparency (where diff images
// almost always do), so we need to clear the canvas so that
// there is no ghosting.
fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
}
fig.context.drawImage(fig.imageObj, 0, 0);
};

this.imageObj.onunload = function() {
fig.ws.close();
}

this.ws.onmessage = this._make_on_message_function(this);

}

mpl.figure.prototype._init_header = function() {
var titlebar = $( '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + 'ui-helper-clearfix"/>'); var titletext =$(
'<div class="ui-dialog-title" style="width: 100%; ' +
'text-align: center; padding: 3px;"/>');
titlebar.append(titletext)
this.root.append(titlebar);
}

mpl.figure.prototype._canvas_extra_style = function(canvas_div) {

}

mpl.figure.prototype._root_extra_style = function(canvas_div) {

}

mpl.figure.prototype._init_canvas = function() {
var fig = this;

var canvas_div = $('<div/>'); canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); function canvas_keyboard_event(event) { return fig.key_event(event, event['data']); } canvas_div.keydown('key_press', canvas_keyboard_event); canvas_div.keyup('key_release', canvas_keyboard_event); this.canvas_div = canvas_div this._canvas_extra_style(canvas_div) this.root.append(canvas_div); var canvas =$('<canvas/>');
canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")

this.canvas = canvas[0];
this.context = canvas[0].getContext("2d");

var backingStore = this.context.backingStorePixelRatio ||
this.context.webkitBackingStorePixelRatio ||
this.context.mozBackingStorePixelRatio ||
this.context.msBackingStorePixelRatio ||
this.context.oBackingStorePixelRatio ||
this.context.backingStorePixelRatio || 1;

mpl.ratio = (window.devicePixelRatio || 1) / backingStore;

var rubberband = $('<canvas/>'); rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") var pass_mouse_events = true; canvas_div.resizable({ start: function(event, ui) { pass_mouse_events = false; }, resize: function(event, ui) { fig.request_resize(ui.size.width, ui.size.height); }, stop: function(event, ui) { pass_mouse_events = true; fig.request_resize(ui.size.width, ui.size.height); }, }); function mouse_event_fn(event) { if (pass_mouse_events) return fig.mouse_event(event, event['data']); } rubberband.mousedown('button_press', mouse_event_fn); rubberband.mouseup('button_release', mouse_event_fn); // Throttle sequential mouse events to 1 every 20ms. rubberband.mousemove('motion_notify', mouse_event_fn); rubberband.mouseenter('figure_enter', mouse_event_fn); rubberband.mouseleave('figure_leave', mouse_event_fn); canvas_div.on("wheel", function (event) { event = event.originalEvent; event['data'] = 'scroll' if (event.deltaY < 0) { event.step = 1; } else { event.step = -1; } mouse_event_fn(event); }); canvas_div.append(canvas); canvas_div.append(rubberband); this.rubberband = rubberband; this.rubberband_canvas = rubberband[0]; this.rubberband_context = rubberband[0].getContext("2d"); this.rubberband_context.strokeStyle = "#000000"; this._resize_canvas = function(width, height) { // Keep the size of the canvas, canvas container, and rubber band // canvas in synch. canvas_div.css('width', width) canvas_div.css('height', height) canvas.attr('width', width * mpl.ratio); canvas.attr('height', height * mpl.ratio); canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); rubberband.attr('width', width); rubberband.attr('height', height); } // Set the figure to an initial 600x600px, this will subsequently be updated // upon first draw. this._resize_canvas(600, 600); // Disable right mouse context menu.$(this.rubberband_canvas).bind("contextmenu",function(e){
return false;
});

function set_focus () {
canvas.focus();
canvas_div.focus();
}

window.setTimeout(set_focus, 100);
}

mpl.figure.prototype._init_toolbar = function() {
var fig = this;

var nav_element = $('<div/>') nav_element.attr('style', 'width: 100%'); this.root.append(nav_element); // Define a callback function for later on. function toolbar_event(event) { return fig.toolbar_button_onclick(event['data']); } function toolbar_mouse_event(event) { return fig.toolbar_button_onmouseover(event['data']); } for(var toolbar_ind in mpl.toolbar_items) { var name = mpl.toolbar_items[toolbar_ind][0]; var tooltip = mpl.toolbar_items[toolbar_ind][1]; var image = mpl.toolbar_items[toolbar_ind][2]; var method_name = mpl.toolbar_items[toolbar_ind][3]; if (!name) { // put a spacer in here. continue; } var button =$('<button/>');
button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
'ui-button-icon-only');
button.attr('role', 'button');
button.attr('aria-disabled', 'false');
button.click(method_name, toolbar_event);
button.mouseover(tooltip, toolbar_mouse_event);

var icon_img = $('<span/>'); icon_img.addClass('ui-button-icon-primary ui-icon'); icon_img.addClass(image); icon_img.addClass('ui-corner-all'); var tooltip_span =$('<span/>');
tooltip_span.html(tooltip);

button.append(icon_img);
button.append(tooltip_span);

nav_element.append(button);
}

var fmt_picker_span = $('<span/>'); var fmt_picker =$('<select/>');
fmt_picker_span.append(fmt_picker);
nav_element.append(fmt_picker_span);
this.format_dropdown = fmt_picker[0];

for (var ind in mpl.extensions) {
var fmt = mpl.extensions[ind];
var option = $( '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); fmt_picker.append(option) } // Add hover states to the ui-buttons$( ".ui-button" ).hover(
function() { $(this).addClass("ui-state-hover");}, function() {$(this).removeClass("ui-state-hover");}
);

var status_bar = $('<span class="mpl-message"/>'); nav_element.append(status_bar); this.message = status_bar[0]; } mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, // which will in turn request a refresh of the image. this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); } mpl.figure.prototype.send_message = function(type, properties) { properties['type'] = type; properties['figure_id'] = this.id; this.ws.send(JSON.stringify(properties)); } mpl.figure.prototype.send_draw_message = function() { if (!this.waiting) { this.waiting = true; this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); } } mpl.figure.prototype.handle_save = function(fig, msg) { var format_dropdown = fig.format_dropdown; var format = format_dropdown.options[format_dropdown.selectedIndex].value; fig.ondownload(fig, format); } mpl.figure.prototype.handle_resize = function(fig, msg) { var size = msg['size']; if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { fig._resize_canvas(size[0], size[1]); fig.send_message("refresh", {}); }; } mpl.figure.prototype.handle_rubberband = function(fig, msg) { var x0 = msg['x0'] / mpl.ratio; var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; var x1 = msg['x1'] / mpl.ratio; var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; x0 = Math.floor(x0) + 0.5; y0 = Math.floor(y0) + 0.5; x1 = Math.floor(x1) + 0.5; y1 = Math.floor(y1) + 0.5; var min_x = Math.min(x0, x1); var min_y = Math.min(y0, y1); var width = Math.abs(x1 - x0); var height = Math.abs(y1 - y0); fig.rubberband_context.clearRect( 0, 0, fig.canvas.width, fig.canvas.height); fig.rubberband_context.strokeRect(min_x, min_y, width, height); } mpl.figure.prototype.handle_figure_label = function(fig, msg) { // Updates the figure title. fig.header.textContent = msg['label']; } mpl.figure.prototype.handle_cursor = function(fig, msg) { var cursor = msg['cursor']; switch(cursor) { case 0: cursor = 'pointer'; break; case 1: cursor = 'default'; break; case 2: cursor = 'crosshair'; break; case 3: cursor = 'move'; break; } fig.rubberband_canvas.style.cursor = cursor; } mpl.figure.prototype.handle_message = function(fig, msg) { fig.message.textContent = msg['message']; } mpl.figure.prototype.handle_draw = function(fig, msg) { // Request the server to send over a new figure. fig.send_draw_message(); } mpl.figure.prototype.handle_image_mode = function(fig, msg) { fig.image_mode = msg['mode']; } mpl.figure.prototype.updated_canvas_event = function() { // Called whenever the canvas gets updated. this.send_message("ack", {}); } // A function to construct a web socket function for onmessage handling. // Called in the figure constructor. mpl.figure.prototype._make_on_message_function = function(fig) { return function socket_on_message(evt) { if (evt.data instanceof Blob) { /* FIXME: We get "Resource interpreted as Image but * transferred with MIME type text/plain:" errors on * Chrome. But how to set the MIME type? It doesn't seem * to be part of the websocket stream */ evt.data.type = "image/png"; /* Free the memory for the previous frames */ if (fig.imageObj.src) { (window.URL || window.webkitURL).revokeObjectURL( fig.imageObj.src); } fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( evt.data); fig.updated_canvas_event(); fig.waiting = false; return; } else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { fig.imageObj.src = evt.data; fig.updated_canvas_event(); fig.waiting = false; return; } var msg = JSON.parse(evt.data); var msg_type = msg['type']; // Call the "handle_{type}" callback, which takes // the figure and JSON message as its only arguments. try { var callback = fig["handle_" + msg_type]; } catch (e) { console.log("No handler for the '" + msg_type + "' message type: ", msg); return; } if (callback) { try { // console.log("Handling '" + msg_type + "' message: ", msg); callback(fig, msg); } catch (e) { console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); } } }; } // from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas mpl.findpos = function(e) { //this section is from http://www.quirksmode.org/js/events_properties.html var targ; if (!e) e = window.event; if (e.target) targ = e.target; else if (e.srcElement) targ = e.srcElement; if (targ.nodeType == 3) // defeat Safari bug targ = targ.parentNode; // jQuery normalizes the pageX and pageY // pageX,Y are the mouse positions relative to the document // offset() returns the position of the element relative to the document var x = e.pageX -$(targ).offset().left;
var y = e.pageY - $(targ).offset().top; return {"x": x, "y": y}; }; /* * return a copy of an object with only non-object keys * we need this to avoid circular references * http://stackoverflow.com/a/24161582/3208463 */ function simpleKeys (original) { return Object.keys(original).reduce(function (obj, key) { if (typeof original[key] !== 'object') obj[key] = original[key] return obj; }, {}); } mpl.figure.prototype.mouse_event = function(event, name) { var canvas_pos = mpl.findpos(event) if (name === 'button_press') { this.canvas.focus(); this.canvas_div.focus(); } var x = canvas_pos.x * mpl.ratio; var y = canvas_pos.y * mpl.ratio; this.send_message(name, {x: x, y: y, button: event.button, step: event.step, guiEvent: simpleKeys(event)}); /* This prevents the web browser from automatically changing to * the text insertion cursor when the button is pressed. We want * to control all of the cursor setting manually through the * 'cursor' event from matplotlib */ event.preventDefault(); return false; } mpl.figure.prototype._key_event_extra = function(event, name) { // Handle any extra behaviour associated with a key event } mpl.figure.prototype.key_event = function(event, name) { // Prevent repeat events if (name == 'key_press') { if (event.which === this._key) return; else this._key = event.which; } if (name == 'key_release') this._key = null; var value = ''; if (event.ctrlKey && event.which != 17) value += "ctrl+"; if (event.altKey && event.which != 18) value += "alt+"; if (event.shiftKey && event.which != 16) value += "shift+"; value += 'k'; value += event.which.toString(); this._key_event_extra(event, name); this.send_message(name, {key: value, guiEvent: simpleKeys(event)}); return false; } mpl.figure.prototype.toolbar_button_onclick = function(name) { if (name == 'download') { this.handle_save(this, null); } else { this.send_message("toolbar_button", {name: name}); } }; mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { this.message.textContent = tooltip; }; 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"]]; mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"]; mpl.default_extension = "png";var comm_websocket_adapter = function(comm) { // Create a "websocket"-like object which calls the given IPython comm // object with the appropriate methods. Currently this is a non binary // socket, so there is still some room for performance tuning. var ws = {}; ws.close = function() { comm.close() }; ws.send = function(m) { //console.log('sending', m); comm.send(m); }; // Register the callback with on_msg. comm.on_msg(function(msg) { //console.log('receiving', msg['content']['data'], msg); // Pass the mpl event to the overridden (by mpl) onmessage function. ws.onmessage(msg['content']['data']) }); return ws; } mpl.mpl_figure_comm = function(comm, msg) { // This is the function which gets called when the mpl process // starts-up an IPython Comm through the "matplotlib" channel. var id = msg.content.data.id; // Get hold of the div created by the display call when the Comm // socket was opened in Python. var element =$("#" + id);
var ws_proxy = comm_websocket_adapter(comm)

window.open(figure.imageObj.src);
}

var fig = new mpl.figure(id, ws_proxy,
element.get(0));

// Call onopen now - mpl needs it, as it is assuming we've passed it a real
// web socket which is closed, not our websocket->open comm proxy.
ws_proxy.onopen();

fig.parent_element = element.get(0);
fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
if (!fig.cell_info) {
console.error("Failed to find cell for figure", id, fig);
return;
}

var output_index = fig.cell_info[2]
var cell = fig.cell_info[0];

};

mpl.figure.prototype.handle_close = function(fig, msg) {
var width = fig.canvas.width/mpl.ratio
fig.root.unbind('remove')

// Update the output cell to use the data from the current canvas.
fig.push_to_output();
var dataURL = fig.canvas.toDataURL();
// Re-enable the keyboard manager in IPython - without this line, in FF,
// the notebook keyboard shortcuts fail.
IPython.keyboard_manager.enable()
$(fig.parent_element).html('<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'); fig.close_ws(fig, msg); } mpl.figure.prototype.close_ws = function(fig, msg){ fig.send_message('closing', msg); // fig.ws.close() } mpl.figure.prototype.push_to_output = function(remove_interactive) { // Turn the data on the canvas into data in the output cell. var width = this.canvas.width/mpl.ratio var dataURL = this.canvas.toDataURL(); this.cell_info[1]['text/html'] = '<amp-img layout="responsive" width="500" height="300" src="' + dataURL + '" width="' + width + '">'; } mpl.figure.prototype.updated_canvas_event = function() { // Tell IPython that the notebook contents must change. IPython.notebook.set_dirty(true); this.send_message("ack", {}); var fig = this; // Wait a second, then push the new image to the DOM so // that it is saved nicely (might be nice to debounce this). setTimeout(function () { fig.push_to_output() }, 1000); } mpl.figure.prototype._init_toolbar = function() { var fig = this; var nav_element =$('<div/>')
nav_element.attr('style', 'width: 100%');
this.root.append(nav_element);

// Define a callback function for later on.
function toolbar_event(event) {
return fig.toolbar_button_onclick(event['data']);
}
function toolbar_mouse_event(event) {
return fig.toolbar_button_onmouseover(event['data']);
}

for(var toolbar_ind in mpl.toolbar_items){
var name = mpl.toolbar_items[toolbar_ind][0];
var tooltip = mpl.toolbar_items[toolbar_ind][1];
var image = mpl.toolbar_items[toolbar_ind][2];
var method_name = mpl.toolbar_items[toolbar_ind][3];

if (!name) { continue; };

var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); button.click(method_name, toolbar_event); button.mouseover(tooltip, toolbar_mouse_event); nav_element.append(button); } // Add the status bar. var status_bar =$('<span class="mpl-message" style="text-align:right; float: right;"/>');
nav_element.append(status_bar);
this.message = status_bar[0];

// Add the close button to the window.
var buttongrp = $('<div class="btn-group inline pull-right"></div>'); 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>');
button.click(function (evt) { fig.handle_close(fig, {}); } );
button.mouseover('Stop Interaction', toolbar_mouse_event);
buttongrp.append(button);
var titlebar = this.root.find($('.ui-dialog-titlebar')); titlebar.prepend(buttongrp); } mpl.figure.prototype._root_extra_style = function(el){ var fig = this el.on("remove", function(){ fig.close_ws(fig, {}); }); } mpl.figure.prototype._canvas_extra_style = function(el){ // this is important to make the div 'focusable el.attr('tabindex', 0) // reach out to IPython and tell the keyboard manager to turn it's self // off when our div gets focus // location in version 3 if (IPython.notebook.keyboard_manager) { IPython.notebook.keyboard_manager.register_events(el); } else { // location in version 2 IPython.keyboard_manager.register_events(el); } } mpl.figure.prototype._key_event_extra = function(event, name) { var manager = IPython.notebook.keyboard_manager; if (!manager) manager = IPython.keyboard_manager; // Check for shift+enter if (event.shiftKey && event.which == 13) { this.canvas_div.blur(); event.shiftKey = false; // Send a "J" for go to next cell event.which = 74; event.keyCode = 74; manager.command_mode(); manager.handle_keydown(event); } } mpl.figure.prototype.handle_save = function(fig, msg) { fig.ondownload(fig, null); } mpl.find_output_cell = function(html_output) { // Return the cell and output element which can be found *uniquely* in the notebook. // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" // IPython event is triggered only after the cells have been serialised, which for // our purposes (turning an active figure into a static one), is too late. var cells = IPython.notebook.get_cells(); var ncells = cells.length; for (var i=0; i<ncells; i++) { var cell = cells[i]; if (cell.cell_type === 'code'){ for (var j=0; j<cell.output_area.outputs.length; j++) { var data = cell.output_area.outputs[j]; if (data.data) { // IPython >= 3 moved mimebundle to data attribute of output data = data.data; } if (data['text/html'] == html_output) { return [cell, data, j]; } } } } } // Register the function which deals with the matplotlib target/channel. // The kernel may be null if the page has been refreshed. if (IPython.notebook.kernel != null) { IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); }  numpy.fft Numpy also has an implementation of FFT (numpy.fft). However, in general the scipy one should be preferred, as it uses more efficient underlying implementations. ## References The next cell change the format of the notebook.  In [29]: from IPython.core.display import HTML def css_styling(): styles = open('./styles/custom_barba.css', 'r').read() return HTML(styles) css_styling()   Out[29]: /* Based on Lorena Barba template available at: https://github.com/barbagroup/AeroPython/blob/master/styles/custom.css*/ @font-face { font-family: "Computer Modern"; src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf'); } div.cell{ width:800px; margin-left:16% !important; margin-right:auto; } h1 { font-family: 'Alegreya Sans', sans-serif; } h2 { font-family: 'Fenix', serif; } h3{ font-family: 'Fenix', serif; margin-top:12px; margin-bottom: 3px; } h4{ font-family: 'Fenix', serif; } h5 { font-family: 'Alegreya Sans', sans-serif; } div.text_cell_render{ font-family: 'Alegreya Sans',Computer Modern, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; line-height: 135%; font-size: 120%; width:600px; margin-left:auto; margin-right:auto; } .CodeMirror{ font-family: "Source Code Pro"; font-size: 90%; } /* .prompt{ display: None; }*/ .text_cell_render h1 { font-weight: 200; font-size: 50pt; line-height: 100%; color:#CD2305; margin-bottom: 0.5em; margin-top: 0.5em; display: block; } .text_cell_render h5 { font-weight: 300; font-size: 16pt; color: #CD2305; font-style: italic; margin-bottom: .5em; margin-top: 0.5em; display: block; } .warning{ color: rgb( 240, 20, 20 ) } MathJax.Hub.Config({ TeX: { extensions: ["AMSmath.js"] }, tex2jax: { inlineMath: [ ['$','\$'], ["\$","\$"] ],
displayMath: [ ['$$','$$'], ["\$","\$"] ]
},
displayAlign: 'center', // Change this to 'center' to center equations.
"HTML-CSS": {
styles: {'.MathJax_Display': {"margin": 4}}
}
});