!date %pylab import matplotlib.pyplot as plt, mpld3, mpld3.plugins mpld3.enable_notebook(d3_url="/files/d3.v3.js") fig = plt.figure() xx = round_(randn(100), 2) yy = round_(randn(100), 2) scatter = plot(xx, yy, 's', color='k', mec='grey', mew=3) fig.plugins = [mpld3.plugins.PointLabelTooltip(scatter[0]), FishEye()] from mpld3.plugins import PluginBase import jinja2 import json class FishEye(PluginBase): """A interactive fish eye distortion plugin""" HTML = jinja2.Template(""" """) FIG_JS = jinja2.Template(""" var a = fig.axes[0], xFisheye = d3.fisheye.scale(function() {return a.x;}).focus(360), yFisheye = d3.fisheye.scale(function() {return a.y;}).focus(90); fig.canvas.on("mousemove", function() { var mouse = d3.mouse(this); xFisheye.focus(mouse[0]); yFisheye.focus(mouse[1]); a.zoomed(true); }); a.xdom = xFisheye; a.xmap = xFisheye; a.x = xFisheye; a.ydom = yFisheye; a.ymap = yFisheye; a.y = yFisheye; """) def __init__(self): self.id = self.generate_unique_id() def _fig_js_args(self): return dict(id=self.id) # monkey patch AXIS_CLASS to take scale from axes even if it has been changed AXIS_CLASS = """ function Axis(axes, position, nticks, tickvalues, tickformat){ this.axes = axes; this.position = position; this.nticks = nticks; this.tickvalues = tickvalues; this.tickformat = tickformat; if (position == "bottom"){ this.transform = "translate(0," + this.axes.height + ")"; this.scale = function() { return this.axes.xdom; }; // changed here, and 3 analogous spots below this.class = "x axis"; }else if (position == "top"){ this.transform = "translate(0,0)" this.scale = function() { return this.axes.xdom; }; // changed this.class = "x axis"; }else if (position == "left"){ this.transform = "translate(0,0)"; this.scale = function() { return this.axes.ydom; }; // changed this.class = "y axis"; }else{ this.transform = "translate(" + this.axes.width + ",0)"; this.scale = function() { return this.axes.ydom; }; // changed this.class = "y axis"; } } Axis.prototype.draw = function(){ this.axis = d3.svg.axis() .scale(this.scale()) // changed here, now scale is a function .orient(this.position) .ticks(this.nticks) .tickValues(this.tickvalues) .tickFormat(this.tickformat); this.elem = this.axes.baseaxes.append('g') .attr("transform", this.transform) .attr("class", this.class) .call(this.axis); }; Axis.prototype.zoomed = function(){ gFig = this.axis; this.axis.scale(this.scale()); this.elem.call(this.axis); }; """ mpld3._js.ALL_FUNCTIONS[2] = AXIS_CLASS